Skip to content

Pythagorean Numerology

A Pythagorean numerology engine that deterministically reduces a querent's birth date to a Life Path and Birthday number. The Life Path reduction method is a configurable option because the two common methods diverge on master numbers (11, 22, 33).

from fortune_telling_core import Querent, ReadingRequest
from fortune_telling_core.traditions.numerology import (
    NUMEROLOGY_DECK,
    NUMEROLOGY_SPREAD,
    build_engine,
)

request = ReadingRequest(
    deck_id=NUMEROLOGY_DECK.id,
    spread_id=NUMEROLOGY_SPREAD.id,
    querent=Querent(
        id="sample",
        display_name="Sample",
        attributes={"birth_datetime": "1987-08-17T00:00:00+00:00"},
    ),
)
reading = build_engine().cast(request)

numerology

NUMEROLOGY_DECK module-attribute

NUMEROLOGY_DECK = Deck(
    id="numerology.deck.numbers.v1",
    symbols=tuple(
        (
            Symbol(
                id=item.symbol_id,
                name=str(item.value),
                attributes={
                    "value": str(item.value),
                    "keyword": item.keyword,
                    "master": "true"
                    if item.master
                    else "false",
                },
            )
        )
        for item in NUMBERS
    ),
)

NUMEROLOGY_SPREAD module-attribute

NUMEROLOGY_SPREAD = Spread(
    id="numerology.spread.birth.v1",
    name="Numerology",
    positions=(
        Position(
            "life_path",
            "Life Path",
            "Core number reduced from the full birth date.",
        ),
        Position(
            "birthday",
            "Birthday",
            "Number reduced from the day of the month.",
        ),
    ),
)

ReductionMethod

Bases: StrEnum

How the Life Path number is reduced from the birth date.

The two widely taught methods diverge only when a master number (11, 22, 33) appears in a component:

  • COMPONENT reduces the month, day, and year separately — each able to surface a master number — then sums and reduces the result. This is the method most numerologists consider correct, and the default.
  • ITERATIVE sums every digit of the whole date at once, then reduces. Simpler, but it can dissolve a master number that COMPONENT preserves.

COMPONENT class-attribute instance-attribute

COMPONENT = 'component'

ITERATIVE class-attribute instance-attribute

ITERATIVE = 'iterative'

NumerologyEngine

NumerologyEngine(
    *,
    reduction_method: ReductionMethod = ReductionMethod.COMPONENT,
)

Bases: AbstractEngine

Pythagorean numerology engine.

The engine deterministically reduces a querent's birth date to a Life Path number and a Birthday number, preserving the master numbers 11, 22, and 33.

Parameters:

Name Type Description Default
reduction_method ReductionMethod

Default Life Path reduction rule used when the request does not specify reduction_method.

COMPONENT
Source code in src/fortune_telling_core/traditions/numerology/engine.py
def __init__(self, *, reduction_method: ReductionMethod = ReductionMethod.COMPONENT) -> None:
    self.reduction_method = reduction_method

id class-attribute instance-attribute

id = 'numerology.engine'

version class-attribute instance-attribute

version = '0.1.0'

reduction_method instance-attribute

reduction_method = reduction_method

deck

deck(request: ReadingRequest) -> Deck

Return the numerology number deck.

Parameters:

Name Type Description Default
request ReadingRequest

Reading request whose deck_id must match NUMEROLOGY_DECK.id.

required

Returns:

Type Description
Deck

The bundled numerology deck.

Raises:

Type Description
ValidationError

If the requested deck is unsupported.

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

    Args:
        request: Reading request whose ``deck_id`` must match
            ``NUMEROLOGY_DECK.id``.

    Returns:
        The bundled numerology deck.

    Raises:
        ValidationError: If the requested deck is unsupported.
    """

    if request.deck_id != NUMEROLOGY_DECK.id:
        raise ValidationError(f"unsupported numerology deck: {request.deck_id}")
    return NUMEROLOGY_DECK

spread

spread(request: ReadingRequest) -> Spread

Return the numerology spread.

Parameters:

Name Type Description Default
request ReadingRequest

Reading request whose spread_id must match NUMEROLOGY_SPREAD.id.

required

Returns:

Type Description
Spread

The bundled numerology spread.

Raises:

Type Description
ValidationError

If the requested spread is unsupported.

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

    Args:
        request: Reading request whose ``spread_id`` must match
            ``NUMEROLOGY_SPREAD.id``.

    Returns:
        The bundled numerology spread.

    Raises:
        ValidationError: If the requested spread is unsupported.
    """

    if request.spread_id != NUMEROLOGY_SPREAD.id:
        raise ValidationError(f"unsupported numerology spread: {request.spread_id}")
    return NUMEROLOGY_SPREAD

draw

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

Compute the numerology numbers as a deterministic draw.

Parameters:

Name Type Description Default
request ReadingRequest

Reading request with birth_datetime and optional reduction_method in options or querent attributes.

required
rng Rng

Ignored. The argument is present for Engine compatibility.

required

Returns:

Type Description
Draw

A draw with the Life Path and Birthday selections.

Raises:

Type Description
ValidationError

If required birth data or options are invalid.

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

    Args:
        request: Reading request with ``birth_datetime`` and optional
            ``reduction_method`` in options or querent attributes.
        rng: Ignored. The argument is present for ``Engine`` compatibility.

    Returns:
        A draw with the Life Path and Birthday selections.

    Raises:
        ValidationError: If required birth data or options are invalid.
    """

    del rng
    birth = parse_birth_data(request, self.reduction_method)
    return draw_from_chart(compute_chart(birth.birth_datetime.date(), birth.method))

cast

cast(request: ReadingRequest) -> Reading

Compute a numerology reading without a caller RNG.

Parameters:

Name Type Description Default
request ReadingRequest

Reading request containing birth data and optional configuration.

required

Returns:

Type Description
Reading

A reading with Life Path and Birthday placements and summary text.

Raises:

Type Description
ValidationError

If required birth data or options are invalid.

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

    Args:
        request: Reading request containing birth data and optional
            configuration.

    Returns:
        A reading with Life Path and Birthday placements and summary text.

    Raises:
        ValidationError: If required birth data or options are invalid.
    """

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

build_engine

build_engine(
    *,
    reduction_method: ReductionMethod = ReductionMethod.COMPONENT,
) -> NumerologyEngine

Create a numerology engine.

Parameters:

Name Type Description Default
reduction_method ReductionMethod

Default Life Path reduction rule.

COMPONENT

Returns:

Type Description
NumerologyEngine

A new NumerologyEngine instance.

Source code in src/fortune_telling_core/traditions/numerology/engine.py
def build_engine(
    *, reduction_method: ReductionMethod = ReductionMethod.COMPONENT
) -> NumerologyEngine:
    """Create a numerology engine.

    Args:
        reduction_method: Default Life Path reduction rule.

    Returns:
        A new ``NumerologyEngine`` instance.
    """

    return NumerologyEngine(reduction_method=reduction_method)