mirror of
https://github.com/migatu/astrololo.git
synced 2026-07-14 21:38:37 +00:00
eef67d37b5
Pierwsza wersja mostu horoskop -> sygnifikatory -> baza (zalążek LOG-16/18/19).
- logic/significators.py: z pozycji generuje tokeny w składni bazy (planeta
[Su, znak [Tau...), pyta warstwę danych o rekordy z tokenem planety i zawęża
do tych, które wspominają też jej znak ("planeta w swoim znaku"); odsiewa szum.
- logic /chart/report: nowy endpoint (pozycje -> raport dopasowań z interpretacjami).
- logic DataClient.search: parametr fields (lżejszy payload).
- data: naprawa str.contains regex=True -> regex=False (sygnifikatory zawierają
[ + itd., metaznaki regex); podniesiony górny limit zapytania (le=50000).
- prezentacja: strona /interpret (formularz -> wyszukane interpretacje per obiekt)
+ nawigacja.
Zweryfikowano end-to-end na realnym pliku (Encyclopaedia of Medical Astrology,
53969 wierszy): dla horoskopu 30.04.1984 znaleziono m.in. Sun w Taurus 46,
Mars w Scorpio 57, Saturn w Scorpio 61 dopasowań; przykłady: "[Su in [Tau" ->
"the bump of amativeness prominent". 15 testów przechodzi.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
89 lines
2.9 KiB
Python
89 lines
2.9 KiB
Python
"""Most: policzony horoskop → tokeny sygnifikatorów → wyszukiwanie w bazie.
|
|
|
|
Pierwsza wersja (LOG-16/18/19 w zalążku): z pozycji obiektów generujemy tokeny w
|
|
składni bazy (np. Słońce w Byku → planeta `[Su`, znak `[Tau`), pytamy warstwę
|
|
danych o rekordy zawierające token planety, a następnie zawężamy do tych, które
|
|
wspominają też jej znak („planeta w swoim znaku"). To realizuje przepływ „wynik
|
|
obliczeń szukany w pliku".
|
|
|
|
Format skrótów odczytany z realnej bazy (Encyclopaedia of Medical Astrology):
|
|
planety `[Su`,`[Mo`,…; znaki `[Ari`,`[Tau`,…; np. `[Su affl. in [Vir`.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from typing import Any, Protocol
|
|
|
|
from app.engine.formats import SIGN_ABBR, sign_index
|
|
|
|
PLANET_ABBR = {
|
|
"Sun": "Su", "Moon": "Mo", "Mercury": "Me", "Venus": "Ve", "Mars": "Ma",
|
|
"Jupiter": "Ju", "Saturn": "Sa", "Uranus": "Ur", "Neptune": "Ne", "Pluto": "Pl",
|
|
}
|
|
|
|
|
|
class DataSource(Protocol):
|
|
def search(
|
|
self, key: str, value: str, exact: bool, limit: int, fields: list[str] | None = None
|
|
) -> dict[str, Any]: ...
|
|
|
|
|
|
def _effect(row: dict) -> str:
|
|
for col in ("actioneffect", "topicresult", "bodypart"):
|
|
v = row.get(col)
|
|
if v and str(v).strip().lower() not in ("", "nan"):
|
|
return str(v).strip()
|
|
return ""
|
|
|
|
|
|
def _is_noise(sig: str, effect: str) -> bool:
|
|
s = sig.strip().lower()
|
|
return (
|
|
not effect
|
|
or s.startswith("significator")
|
|
or "header" in s
|
|
or s in ("x", "x?", "nan")
|
|
)
|
|
|
|
|
|
def build_report(positions, data: DataSource, per_object_limit: int = 60) -> dict:
|
|
"""Dla każdego obiektu: wyszukaj sygnifikatory planety i zawęź do jej znaku."""
|
|
items: list[dict] = []
|
|
provider = None
|
|
for p in positions:
|
|
if p.name not in PLANET_ABBR:
|
|
continue
|
|
planet_tok = "[" + PLANET_ABBR[p.name]
|
|
sign_tok = "[" + SIGN_ABBR[sign_index(p.longitude)]
|
|
|
|
raw = data.search(
|
|
key="significator",
|
|
value=planet_tok,
|
|
exact=False,
|
|
limit=per_object_limit,
|
|
fields=["significator", "actioneffect", "topicresult", "bodypart"],
|
|
)
|
|
provider = raw.get("provider", provider)
|
|
rows = raw.get("rows", [])
|
|
|
|
samples: list[dict] = []
|
|
for r in rows:
|
|
sig = str(r.get("significator") or "")
|
|
if sign_tok.lower() not in sig.lower():
|
|
continue
|
|
eff = _effect(r)
|
|
if _is_noise(sig, eff):
|
|
continue
|
|
samples.append({"significator": sig.strip(), "effect": eff})
|
|
|
|
items.append({
|
|
"object": p.name,
|
|
"sign": p.sign,
|
|
"direction": p.direction,
|
|
"planet_token": planet_tok,
|
|
"sign_token": sign_tok,
|
|
"planet_total": raw.get("total", 0),
|
|
"in_sign_count": len(samples),
|
|
"samples": samples[:5],
|
|
})
|
|
return {"provider": provider, "objects": items}
|