Skip to content

Javanese Weton

A Javanese weton (Primbon) engine that deterministically derives a querent's weton (seven saptawara days paired with five pancawara pasaran) and neptu from their birth datetime.

from fortune_telling_core import Querent, ReadingRequest
from fortune_telling_core.traditions.weton import WETON_DECK, WETON_SPREAD, build_engine

request = ReadingRequest(
    deck_id=WETON_DECK.id,
    spread_id=WETON_SPREAD.id,
    querent=Querent(
        id="sample",
        display_name="Sample",
        attributes={"birth_datetime": "1945-08-17T10:00:00+07:00"},
    ),
)
reading = build_engine().cast(request)

weton

WETON_DECK module-attribute

WETON_DECK = Deck(
    id="weton.deck.javanese.v1",
    symbols=(
        *(
            (
                Symbol(
                    id=day.symbol_id,
                    name=day.name,
                    attributes={
                        "cycle": "saptawara",
                        "slug": day.slug,
                        "javanese": day.javanese,
                        "weekday": str(day.weekday),
                        "neptu": str(day.neptu),
                    },
                )
            )
            for day in SAPTAWARA
        ),
        *(
            (
                Symbol(
                    id=pasaran.symbol_id,
                    name=pasaran.name,
                    attributes={
                        "cycle": "pancawara",
                        "slug": pasaran.slug,
                        "javanese": pasaran.javanese,
                        "index": str(pasaran.index),
                        "neptu": str(pasaran.neptu),
                    },
                )
            )
            for pasaran in PANCAWARA
        ),
    ),
)

WETON_SPREAD module-attribute

WETON_SPREAD = Spread(
    id="weton.spread.birth.v1",
    name="Weton",
    positions=(
        Position(
            "saptawara",
            "Saptawara",
            "Day of the seven-day week with its neptu.",
        ),
        Position(
            "pancawara",
            "Pancawara",
            "Pasaran of the five-day market week with its neptu.",
        ),
    ),
)

DayBoundary

Bases: StrEnum

When the Javanese day (and therefore the weton) rolls over.

The Javanese day traditionally begins at sunset rather than at midnight, so an evening birth can belong to the following weton. Sunset times depend on location, so this dependency-free engine approximates the sunset boundary with a fixed local-clock threshold of 18:00.

MIDNIGHT class-attribute instance-attribute

MIDNIGHT = 'midnight'

SUNSET class-attribute instance-attribute

SUNSET = 'sunset'

WetonEngine

WetonEngine(
    *, day_boundary: DayBoundary = DayBoundary.MIDNIGHT
)

Bases: AbstractEngine

Javanese weton engine.

The engine deterministically derives the saptawara (seven-day week) and pancawara (five-day pasaran) from a birth datetime, then records both with their neptu values and the combined weton neptu.

Parameters:

Name Type Description Default
day_boundary DayBoundary

Default Javanese day-rollover rule used when the request does not specify day_boundary.

MIDNIGHT
Source code in src/fortune_telling_core/traditions/weton/engine.py
def __init__(self, *, day_boundary: DayBoundary = DayBoundary.MIDNIGHT) -> None:
    self.day_boundary = day_boundary

id class-attribute instance-attribute

id = 'weton.engine'

version class-attribute instance-attribute

version = '0.1.0'

day_boundary instance-attribute

day_boundary = day_boundary

deck

deck(request: ReadingRequest) -> Deck

Return the weton deck.

Parameters:

Name Type Description Default
request ReadingRequest

Reading request whose deck_id must match WETON_DECK.id.

required

Returns:

Type Description
Deck

The bundled weton deck.

Raises:

Type Description
ValidationError

If the requested deck is unsupported.

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

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

    Returns:
        The bundled weton deck.

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

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

spread

spread(request: ReadingRequest) -> Spread

Return the weton spread.

Parameters:

Name Type Description Default
request ReadingRequest

Reading request whose spread_id must match WETON_SPREAD.id.

required

Returns:

Type Description
Spread

The bundled weton spread.

Raises:

Type Description
ValidationError

If the requested spread is unsupported.

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

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

    Returns:
        The bundled weton spread.

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

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

draw

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

Compute the weton as a deterministic draw.

Parameters:

Name Type Description Default
request ReadingRequest

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

required
rng Rng

Ignored. The argument is present for Engine compatibility.

required

Returns:

Type Description
Draw

A draw with saptawara and pancawara selections.

Raises:

Type Description
ValidationError

If required birth data or options are invalid.

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

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

    Returns:
        A draw with saptawara and pancawara selections.

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

    del rng
    birth = parse_birth_data(request, self.day_boundary)
    chart = compute_weton(birth.birth_datetime, birth.day_boundary)
    return draw_from_chart(chart, birth.day_boundary)

cast

cast(request: ReadingRequest) -> Reading

Compute a weton 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 saptawara and pancawara placements and weton summary

Reading

text.

Raises:

Type Description
ValidationError

If required birth data or options are invalid.

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

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

    Returns:
        A reading with saptawara and pancawara placements and weton 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(
    *, day_boundary: DayBoundary = DayBoundary.MIDNIGHT
) -> WetonEngine

Create a weton engine.

Parameters:

Name Type Description Default
day_boundary DayBoundary

Default Javanese day-rollover rule.

MIDNIGHT

Returns:

Type Description
WetonEngine

A new WetonEngine instance.

Source code in src/fortune_telling_core/traditions/weton/engine.py
def build_engine(*, day_boundary: DayBoundary = DayBoundary.MIDNIGHT) -> WetonEngine:
    """Create a weton engine.

    Args:
        day_boundary: Default Javanese day-rollover rule.

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

    return WetonEngine(day_boundary=day_boundary)