bases.alphabet.string_alphabet API documentation
Description: Alphabets explicitly specified by strings.

# Module `bases.alphabet.string_alphabet`

Alphabets explicitly specified by strings.

Expand source code

    """
        Alphabets explicitly specified by strings.
    """

    from types import MappingProxyType
    from typing import Any, Mapping, overload, Union

    from .abstract import Alphabet

    class StringAlphabet(Alphabet):
        """
            Class for alphabets explicitly specified by a string of (unique) characters
            and optional case sensitivity (default: case-sensitive).

            Example usage:

            ```py
            >>> from bases.alphabet import StringAlphabet
            >>> StringAlphabet("0123456789abcdef", case_sensitive=False)
            StringAlphabet('0123456789abcdef', case_sensitive=False)
            >>> StringAlphabet("0123").case_sensitive
            True
            ```
        """

        _chars: str
        _revdir: Mapping[str, int]
        _case_sensitive: bool

        def __init__(self, chars: str, *,
                     case_sensitive: bool = True):
            super().__init__(case_sensitive)
            self._chars = chars
            revdir = {
                c: idx for idx, c in enumerate(chars)
            }
            if not case_sensitive:
                revdir.update({
                    c.upper(): idx for idx, c in enumerate(chars)
                })
                revdir.update({
                    c.lower(): idx for idx, c in enumerate(chars)
                })
            self._revdir = MappingProxyType(revdir)
            self.__validate_init()

        def __validate_init(self) -> None:
            chars = self._chars
            case_sensitive = self.case_sensitive
            if len(chars) <= 1:
                raise ValueError("Alphabet must have at least two characters.")
            if len(chars) != len(set(chars)):
                raise ValueError("Alphabet cannot contain repeated characters.")
            if not case_sensitive:
                chars_set_upper = {c.upper() for c in chars}
                chars_set_lower = {c.lower() for c in chars}
                if len(chars_set_upper) != len(chars) or len(chars_set_lower) != len(chars):
                    raise ValueError("Alphabet contains lowercase and uppercase versions of the same character, "
                                     "encoding must be case-sensitive.")

        @property
        def chars(self) -> str:
            """
                The characters that define this alphabet.

                Example usage:

                ```py
                >>> alphabet.base16.chars
                '0123456789ABCDEF'
                ```
            """
            return self._chars

        @property
        def revdir(self) -> Mapping[str, int]:
            return self._revdir

        def __len__(self) -> int:
            return len(self._chars)

        @overload
        def __getitem__(self, idx: int) -> str:
            ...

        @overload
        def __getitem__(self, idx: slice) -> "StringAlphabet":
            ...

        def __getitem__(self, idx: Union[int, slice]) -> Union[str, "StringAlphabet"]:
            if isinstance(idx, slice):
                new_chars = self._chars[idx]
                return StringAlphabet(new_chars, case_sensitive=self.case_sensitive)
            return self._chars[idx]

        def with_case_sensitivity(self, case_sensitive: bool) -> "StringAlphabet":
            if case_sensitive == self.case_sensitive:
                return self
            return StringAlphabet(self.chars, case_sensitive=case_sensitive)

        def upper(self) -> "StringAlphabet":
            chars = self.chars.upper()
            if chars == self.chars:
                return self
            return StringAlphabet(chars, case_sensitive=self.case_sensitive)

        def lower(self) -> "StringAlphabet":
            chars = self.chars.lower()
            if chars == self.chars:
                return self
            return StringAlphabet(chars, case_sensitive=self.case_sensitive)

        def __eq__(self, other: Any) -> bool:
            if not isinstance(other, StringAlphabet):
                return NotImplemented
            return self.chars == other.chars and self.case_sensitive == other.case_sensitive

        def __hash__(self) -> int:
            return hash((type(self), self.chars, self.case_sensitive))

        def __repr__(self) -> str:
            chars_str = repr(self.chars)
            if self.case_sensitive:
                return f"StringAlphabet({chars_str})"
            case_sensitive_str = f"case_sensitive={self.case_sensitive}"
            return f"StringAlphabet({chars_str}, {case_sensitive_str})"

## Classes

`class StringAlphabet (chars: str, *, case_sensitive: bool = True)`

  Class for alphabets explicitly specified by a string of (unique) characters and optional case sensitivity (default: case-sensitive).

  Example usage:

      >>> from bases.alphabet import StringAlphabet
      >>> StringAlphabet("0123456789abcdef", case_sensitive=False)
      StringAlphabet('0123456789abcdef', case_sensitive=False)
      >>> StringAlphabet("0123").case_sensitive
      True

  Expand source code

      class StringAlphabet(Alphabet):
          """
              Class for alphabets explicitly specified by a string of (unique) characters
              and optional case sensitivity (default: case-sensitive).

              Example usage:

              ```py
              >>> from bases.alphabet import StringAlphabet
              >>> StringAlphabet("0123456789abcdef", case_sensitive=False)
              StringAlphabet('0123456789abcdef', case_sensitive=False)
              >>> StringAlphabet("0123").case_sensitive
              True
              ```
          """

          _chars: str
          _revdir: Mapping[str, int]
          _case_sensitive: bool

          def __init__(self, chars: str, *,
                       case_sensitive: bool = True):
              super().__init__(case_sensitive)
              self._chars = chars
              revdir = {
                  c: idx for idx, c in enumerate(chars)
              }
              if not case_sensitive:
                  revdir.update({
                      c.upper(): idx for idx, c in enumerate(chars)
                  })
                  revdir.update({
                      c.lower(): idx for idx, c in enumerate(chars)
                  })
              self._revdir = MappingProxyType(revdir)
              self.__validate_init()

          def __validate_init(self) -> None:
              chars = self._chars
              case_sensitive = self.case_sensitive
              if len(chars) <= 1:
                  raise ValueError("Alphabet must have at least two characters.")
              if len(chars) != len(set(chars)):
                  raise ValueError("Alphabet cannot contain repeated characters.")
              if not case_sensitive:
                  chars_set_upper = {c.upper() for c in chars}
                  chars_set_lower = {c.lower() for c in chars}
                  if len(chars_set_upper) != len(chars) or len(chars_set_lower) != len(chars):
                      raise ValueError("Alphabet contains lowercase and uppercase versions of the same character, "
                                       "encoding must be case-sensitive.")

          @property
          def chars(self) -> str:
              """
                  The characters that define this alphabet.

                  Example usage:

                  ```py
                  >>> alphabet.base16.chars
                  '0123456789ABCDEF'
                  ```
              """
              return self._chars

          @property
          def revdir(self) -> Mapping[str, int]:
              return self._revdir

          def __len__(self) -> int:
              return len(self._chars)

          @overload
          def __getitem__(self, idx: int) -> str:
              ...

          @overload
          def __getitem__(self, idx: slice) -> "StringAlphabet":
              ...

          def __getitem__(self, idx: Union[int, slice]) -> Union[str, "StringAlphabet"]:
              if isinstance(idx, slice):
                  new_chars = self._chars[idx]
                  return StringAlphabet(new_chars, case_sensitive=self.case_sensitive)
              return self._chars[idx]

          def with_case_sensitivity(self, case_sensitive: bool) -> "StringAlphabet":
              if case_sensitive == self.case_sensitive:
                  return self
              return StringAlphabet(self.chars, case_sensitive=case_sensitive)

          def upper(self) -> "StringAlphabet":
              chars = self.chars.upper()
              if chars == self.chars:
                  return self
              return StringAlphabet(chars, case_sensitive=self.case_sensitive)

          def lower(self) -> "StringAlphabet":
              chars = self.chars.lower()
              if chars == self.chars:
                  return self
              return StringAlphabet(chars, case_sensitive=self.case_sensitive)

          def __eq__(self, other: Any) -> bool:
              if not isinstance(other, StringAlphabet):
                  return NotImplemented
              return self.chars == other.chars and self.case_sensitive == other.case_sensitive

          def __hash__(self) -> int:
              return hash((type(self), self.chars, self.case_sensitive))

          def __repr__(self) -> str:
              chars_str = repr(self.chars)
              if self.case_sensitive:
                  return f"StringAlphabet({chars_str})"
              case_sensitive_str = f"case_sensitive={self.case_sensitive}"
              return f"StringAlphabet({chars_str}, {case_sensitive_str})"

  ### Ancestors

  - Alphabet
  - abc.ABC
  - collections.abc.Sequence
  - collections.abc.Reversible
  - collections.abc.Collection
  - collections.abc.Sized
  - collections.abc.Iterable
  - collections.abc.Container
  - typing.Generic

  ### Instance variables

  `var chars : str`

    The characters that define this alphabet.

    Example usage:

        >>> alphabet.base16.chars
        '0123456789ABCDEF'

    Expand source code

        @property
        def chars(self) -> str:
            """
                The characters that define this alphabet.

                Example usage:

                ```py
                >>> alphabet.base16.chars
                '0123456789ABCDEF'
                ```
            """
            return self._chars

  ### Inherited members

  - `Alphabet`:
    - `case_sensitive`
    - `count`
    - `index`
    - `lower`
    - `revdir`
    - `upper`
    - `with_case_sensitivity`