Skip to content

Modern Cyrillic Pythagorean Numerology

A modern Russian "Pythagorean-style" numerology engine that reduces a Cyrillic name to a root number (1-9) using a position map across the 33-letter Russian alphabet (1=аисъ, 2=бйты … 9=зрщ). The alphabet/language and the handling of ё, short-i (й), and the hard/soft signs (ъ, ь) are configurable; unsupported letters are rejected.

from fortune_telling_core import Querent, ReadingRequest
from fortune_telling_core.traditions.cyrillic_pythagorean import (
    CYRILLIC_PYTHAGOREAN_DECK,
    CYRILLIC_PYTHAGOREAN_SPREAD,
    build_engine,
)

request = ReadingRequest(
    deck_id=CYRILLIC_PYTHAGOREAN_DECK.id,
    spread_id=CYRILLIC_PYTHAGOREAN_SPREAD.id,
    querent=Querent(id="sample", display_name="Sample", attributes={"name": "Иван"}),
)
reading = build_engine().cast(request)

cyrillic_pythagorean

CYRILLIC_PYTHAGOREAN_DECK module-attribute

CYRILLIC_PYTHAGOREAN_DECK = Deck(
    id="cyrillic_pythagorean.deck.numbers.v1",
    symbols=tuple(
        (
            Symbol(
                id=f"cyrillic_pythagorean.number.{value}",
                name=str(value),
                attributes={
                    "value": str(value),
                    "kind": "root",
                },
            )
        )
        for value in (range(1, 10))
    ),
)

CYRILLIC_PYTHAGOREAN_SPREAD module-attribute

CYRILLIC_PYTHAGOREAN_SPREAD = Spread(
    id="cyrillic_pythagorean.spread.name.v1",
    name="Cyrillic Pythagorean Name Number",
    positions=(
        Position(
            "name_number",
            "Name Number",
            "Root number reduced from the name.",
        ),
    ),
)

Alphabet

Bases: StrEnum

Explicit alphabet tables.

RUSSIAN_33 class-attribute instance-attribute

RUSSIAN_33 = 'russian_33'

RUSSIAN_32_NO_YO class-attribute instance-attribute

RUSSIAN_32_NO_YO = 'russian_32_no_yo'

UKRAINIAN_33 class-attribute instance-attribute

UKRAINIAN_33 = 'ukrainian_33'

SERBIAN_30 class-attribute instance-attribute

SERBIAN_30 = 'serbian_30'

BULGARIAN_30 class-attribute instance-attribute

BULGARIAN_30 = 'bulgarian_30'

Language

Bases: StrEnum

Supported Cyrillic alphabets.

RUSSIAN class-attribute instance-attribute

RUSSIAN = 'russian'

UKRAINIAN class-attribute instance-attribute

UKRAINIAN = 'ukrainian'

SERBIAN class-attribute instance-attribute

SERBIAN = 'serbian'

BULGARIAN class-attribute instance-attribute

BULGARIAN = 'bulgarian'

NormalizationMode

Bases: StrEnum

Supported normalization modes.

STRICT_CYRILLIC class-attribute instance-attribute

STRICT_CYRILLIC = 'strict_cyrillic'

ShortIMode

Bases: StrEnum

How short i is handled.

DISTINCT class-attribute instance-attribute

DISTINCT = 'distinct'

FOLD_TO_I class-attribute instance-attribute

FOLD_TO_I = 'fold_to_i'

SignsMode

Bases: StrEnum

How hard and soft signs are handled.

COUNT class-attribute instance-attribute

COUNT = 'count'

IGNORE_HARD_SOFT_SIGNS class-attribute instance-attribute

IGNORE_HARD_SOFT_SIGNS = 'ignore_hard_soft_signs'

YoMode

Bases: StrEnum

How Russian yo is handled.

DISTINCT class-attribute instance-attribute

DISTINCT = 'distinct'

FOLD_TO_E class-attribute instance-attribute

FOLD_TO_E = 'fold_to_e'

CyrillicPythagoreanEngine

Bases: AbstractEngine

Modern Cyrillic Pythagorean numerology engine.

id class-attribute instance-attribute

id = 'cyrillic_pythagorean.engine'

version class-attribute instance-attribute

version = '0.1.0'

deck

deck(request: ReadingRequest) -> Deck

Return the Cyrillic Pythagorean deck.

Source code in src/fortune_telling_core/traditions/cyrillic_pythagorean/engine.py
def deck(self, request: ReadingRequest) -> Deck:
    """Return the Cyrillic Pythagorean deck."""

    if request.deck_id != CYRILLIC_PYTHAGOREAN_DECK.id:
        raise ValidationError(f"unsupported Cyrillic Pythagorean deck: {request.deck_id}")
    return CYRILLIC_PYTHAGOREAN_DECK

spread

spread(request: ReadingRequest) -> Spread

Return the Cyrillic Pythagorean spread.

Source code in src/fortune_telling_core/traditions/cyrillic_pythagorean/engine.py
def spread(self, request: ReadingRequest) -> Spread:
    """Return the Cyrillic Pythagorean spread."""

    if request.spread_id != CYRILLIC_PYTHAGOREAN_SPREAD.id:
        raise ValidationError(f"unsupported Cyrillic Pythagorean spread: {request.spread_id}")
    return CYRILLIC_PYTHAGOREAN_SPREAD

draw

draw(request: ReadingRequest, rng: Rng) -> Draw

Compute the Cyrillic Pythagorean name number as a deterministic draw.

Source code in src/fortune_telling_core/traditions/cyrillic_pythagorean/engine.py
def draw(self, request: ReadingRequest, rng: Rng) -> Draw:
    """Compute the Cyrillic Pythagorean name number as a deterministic draw."""

    del rng
    fields = collect_values(request)
    name = require_string(fields, "name")
    language = _parse(fields.get("language"), Language.RUSSIAN)
    alphabet = _parse_optional_alphabet(fields.get("alphabet"))
    yo_mode = _parse(fields.get("yo_mode"), YoMode.DISTINCT)
    signs_mode = _parse(fields.get("signs_mode"), SignsMode.COUNT)
    short_i_mode = _parse(fields.get("short_i_mode"), ShortIMode.DISTINCT)
    normalization = _parse(fields.get("normalization"), NormalizationMode.STRICT_CYRILLIC)

    units = cyrillic_pythagorean.values(
        name,
        language=language,
        alphabet=alphabet,
        yo_mode=yo_mode,
        signs_mode=signs_mode,
        short_i_mode=short_i_mode,
        normalization=normalization,
    )
    if not units:
        raise ValidationError("name must contain at least one Cyrillic letter")
    total = cyrillic_pythagorean.total(units)
    root = cyrillic_pythagorean.reduce_to_root(total)
    resolved_alphabet = alphabet or cyrillic_pythagorean._DEFAULT_ALPHABET[language]

    selection = Selection(
        "name_number",
        f"cyrillic_pythagorean.number.{root}",
        {
            "value": str(root),
            "total": str(total),
            "value_system": cyrillic_pythagorean.ID,
            "value_system_version": cyrillic_pythagorean.VERSION,
            "language": language.value,
            "alphabet": resolved_alphabet.value,
            "yo_mode": yo_mode.value,
            "signs_mode": signs_mode.value,
            "short_i_mode": short_i_mode.value,
            "normalization": normalization.value,
            "normalized_name": "".join(unit.char for unit in units),
            "values": format_value_trace(units),
        },
    )
    return Draw(CYRILLIC_PYTHAGOREAN_DECK.id, CYRILLIC_PYTHAGOREAN_SPREAD.id, (selection,))

cast

cast(request: ReadingRequest) -> Reading

Compute a Cyrillic Pythagorean reading without a caller RNG.

Source code in src/fortune_telling_core/traditions/cyrillic_pythagorean/engine.py
def cast(self, request: ReadingRequest) -> Reading:
    """Compute a Cyrillic Pythagorean reading without a caller RNG."""

    draw = self.draw(request, _NULL_RNG)
    return self._interpret(request, draw, rng=None)

build_engine

build_engine() -> CyrillicPythagoreanEngine

Create a Cyrillic Pythagorean numerology engine.

Source code in src/fortune_telling_core/traditions/cyrillic_pythagorean/engine.py
def build_engine() -> CyrillicPythagoreanEngine:
    """Create a Cyrillic Pythagorean numerology engine."""

    return CyrillicPythagoreanEngine()