Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE][DOC][MAINTENANCE] Add structure to generate permutations #89

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ The version is represented by three digits: a.b.c.

## Unreleased

FEATURE:
- `generators`: add structure to generate permutations

## \[0.0.5\] - 2024-06-01

Expand Down
1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ with the symmetric group and its elements.

pages/API_reference/elements/index
pages/API_reference/groups/index
pages/API_reference/generators/index

.. toctree::
:maxdepth: 1
Expand Down
26 changes: 26 additions & 0 deletions docs/source/pages/API_reference/generators/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Generators
==========

`Symmetria` provides a way to generate all the permutations of a given degree. The generation follows different
algorithms which can be specified.


A list of implemented algorithms to generate permutations:

.. list-table:: overview
:widths: 35 50 15
:header-rows: 1

* - Algorithm
- Description
- Reference
* - ``lexicographic``
- The permutations are generate following the lexicographic order.
- here


.. toctree::
:maxdepth: 1
:hidden:

permutation_generator
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Permutation Generator
=====================

To use the generator of permutation, import it as

.. code-block:: python

from symmetria import permutation_generator


The API of the method is given as following:

.. automodule:: symmetria
:members: permutation_generator
:exclude-members: Cycle, CycleDecomposition, Permutation
3 changes: 2 additions & 1 deletion symmetria/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import sys

from symmetria.elements.cycle import Cycle
from symmetria.generators.api import permutation_generator
from symmetria.elements.permutation import Permutation
from symmetria.elements.cycle_decomposition import CycleDecomposition

__version__ = "0.0.5"
__all__ = ["__version__", "Permutation", "Cycle", "CycleDecomposition"]
__all__ = ["__version__", "permutation_generator", "Permutation", "Cycle", "CycleDecomposition"]


def _log_version() -> None:
Expand Down
Empty file.
69 changes: 69 additions & 0 deletions symmetria/generators/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from typing import List, Generator

__all__ = ["permutation_generator"]

_SUPPORTED_ALGORITHM: List[str] = [
"lexicographic",
]


def permutation_generator(degree: int, algorithm: str = "lexicographic") -> Generator["Permutation", None, None]:
"""Generate all the permutations of the degree based on the chosen algorithm.

The method generates all the permutations of the given degree using the specified algorithm.

:param degree: The degree of the permutations to be generated. Must be a non-zero positive integer.
:type degree: int
:param algorithm: The algorithm to use for generating permutations. Default is "lexicographic".
:type algorithm: str, optional

:return: A generator yielding permutations.
:rtype: Generator["Permutation", None, None]

:raises ValueError: If the algorithm is not supported or the degree is invalid.

# Activate once we have the lexicographic algorithm
#:examples:
# >>> from symmetria import permutation_generator
# ...
# >>> permutations = permutation_generator(degree=3, algorithm="lexicographic")
# >>> for perm in permutations:
# ... print(perm)
# Permutation(1, 2, 3)
# Permutation(1, 3, 2)
# Permutation(2, 1, 3)
...
"""
_check_algorithm_parameter(value=algorithm)
_check_degree_parameter(value=degree)
return _relevant_generator(algorithm=algorithm, degree=degree)


def _check_algorithm_parameter(value: str) -> None:
"""Private method to check the value provided for the parameter `algorithm`.

Recall that the parameter `algorithm` must be a string present in the list _SUPPORTED_ALGORITHM
"""
if isinstance(value, str) is False:
raise TypeError(f"The parameter `algorithm` must be of type string, but {type(value)} was provided.")
if value not in _SUPPORTED_ALGORITHM:
raise ValueError(
f"The given algorithm ({value}) is not supported. \n "
f"Here, a list of supported algorithm for generations of permutations {_SUPPORTED_ALGORITHM}."
)


def _check_degree_parameter(value: int) -> None:
"""Private method to check the value provided for the parameter `degree`.

Recall that the parameter `degree` must be a non-negative integer different from zero.
"""
if isinstance(value, int) is False:
raise TypeError(f"The parameter `degree` must be of type int, but {type(value)} was provided.")
if value < 1:
raise ValueError(f"The parameter `degree` must be a non-zero positive integer, but {value} was provided.")


def _relevant_generator(algorithm: str, degree: int) -> Generator["Permutation", None, None]:
"""Private method to pick the correct algorithm for generating permutations."""
raise NotImplementedError(f"To be implemented using {algorithm} and {degree}.")
Empty file.
14 changes: 14 additions & 0 deletions tests/tests_generators/test_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import pytest

from symmetria import permutation_generator
from tests.tests_generators.test_cases import TEST_PERMUTATION_GENERATOR_EXCPETIONS


@pytest.mark.parametrize(
argnames="algorithm, degree, error, msg",
argvalues=TEST_PERMUTATION_GENERATOR_EXCPETIONS,
ids=[f"permutation_generator({a}, {d})" for a, d, _, _ in TEST_PERMUTATION_GENERATOR_EXCPETIONS],
)
def test_permutation_generator_exceptions(algorithm, degree, error, msg) -> None:
with pytest.raises(error, match=msg):
_ = permutation_generator(algorithm=algorithm, degree=degree)
6 changes: 6 additions & 0 deletions tests/tests_generators/test_cases.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
TEST_PERMUTATION_GENERATOR_EXCPETIONS = [
(13, 3, TypeError, "The parameter `algorithm` must be of type string"),
("test", 3, ValueError, "The given algorithm"),
("lexicographic", "test", TypeError, "The parameter `degree`"),
("lexicographic", 0, ValueError, "The parameter `degree` must be a non-zero positive integer"),
]
Loading