mirror of
https://github.com/migatu/astrololo.git
synced 2026-07-14 21:38:37 +00:00
Odsiewanie szumu + rozwijanie skrótów sygnifikatorów
- abbreviations.py: słownik skrót -> pełna nazwa (z SIGNIFICATORS KEY, built-in) + expand(): [Su in [Tau -> "Sun in Taurus", [Sa in 6th H. -> "...6th house", affl. -> afflicted itd. - significators: każda próbka ma pole "expanded" (postać czytelna); hartowanie filtra szumu (efekty zastępcze x/?/-, wiersze *MARKER, legendy/nagłówki). - prezentacja /interpret: pokazuje rozwiniętą postać, surowy skrót w tooltipie. Zweryfikowano na realnym main_base.xlsx: "[Sa or [Ma in the 5th H." -> "Saturn or Mars in the 5th house". 9 testów przechodzi (w tym test_abbreviations). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,58 @@
|
|||||||
|
"""Rozwijanie skrótów sygnifikatorów do postaci czytelnej (na bazie SIGNIFICATORS KEY).
|
||||||
|
|
||||||
|
W bazie zapis jest skrótowy z prefiksem `[` (np. `[Su in [Tau`, `[Sa [conj [Su in 6th H.`).
|
||||||
|
Ten moduł zamienia go na tekst czytelny: „Sun in Taurus", „Saturn conjunction Sun
|
||||||
|
in 6th house". Słownik pochodzi z pliku SIGNIFICATORS KEY (mały, stabilny — wpięty
|
||||||
|
jako built-in; można rozszerzać).
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
# skrót (bez nawiasu) -> pełna nazwa
|
||||||
|
ABBREVIATIONS: dict[str, str] = {
|
||||||
|
# znaki zodiaku
|
||||||
|
"Ari": "Aries", "Tau": "Taurus", "Gem": "Gemini", "Can": "Cancer",
|
||||||
|
"Leo": "Leo", "Vir": "Virgo", "Lib": "Libra", "Sco": "Scorpio",
|
||||||
|
"Sag": "Sagittarius", "Cap": "Capricorn", "Aqu": "Aquarius", "Pis": "Pisces",
|
||||||
|
# planety klasyczne + światła
|
||||||
|
"Su": "Sun", "Mo": "Moon", "Me": "Mercury", "Ve": "Venus",
|
||||||
|
"Ma": "Mars", "Ju": "Jupiter", "Sa": "Saturn",
|
||||||
|
# planety nowożytne
|
||||||
|
"Ur": "Uranus", "Ne": "Neptune", "Pl": "Pluto",
|
||||||
|
# węzły i punkty
|
||||||
|
"NN": "North Node", "SN": "South Node", "Lilith": "Lilith", "Chiron": "Chiron",
|
||||||
|
# osie
|
||||||
|
"Asc": "Ascendant", "Dsc": "Descendant", "MC": "Midheaven", "IC": "Imum Coeli",
|
||||||
|
# aspekty
|
||||||
|
"conj": "conjunction", "sex": "sextile", "sq": "square", "tri": "trine",
|
||||||
|
"opp": "opposition", "semisex": "semisextile", "semisq": "semisquare",
|
||||||
|
"sesquisq": "sesquisquare", "quincunx": "quincunx", "asp": "aspect",
|
||||||
|
# domy jako tokeny [h1..[h12
|
||||||
|
**{f"h{i}": f"{i}th house" for i in range(1, 13)},
|
||||||
|
# ruch
|
||||||
|
"Rx": "retrograde", "R": "retrograde",
|
||||||
|
}
|
||||||
|
# poprawki nieregularnych liczebników domów
|
||||||
|
ABBREVIATIONS.update({"h1": "1st house", "h2": "2nd house", "h3": "3rd house"})
|
||||||
|
|
||||||
|
# rozwinięcia słów spoza składni `[`
|
||||||
|
_WORDS = {
|
||||||
|
"affl.": "afflicted",
|
||||||
|
"P. Dec.": "parallel of declination",
|
||||||
|
"espec.": "especially",
|
||||||
|
}
|
||||||
|
|
||||||
|
_TOKEN = re.compile(r"\[([A-Za-z]+)")
|
||||||
|
_HOUSE = re.compile(r"(\d+(?:st|nd|rd|th))\s*H\.", re.IGNORECASE)
|
||||||
|
|
||||||
|
|
||||||
|
def expand(text: str) -> str:
|
||||||
|
"""Zamienia skróty na pełne nazwy; nieznane tokeny zostawia bez nawiasu."""
|
||||||
|
if not text:
|
||||||
|
return text
|
||||||
|
out = _TOKEN.sub(lambda m: ABBREVIATIONS.get(m.group(1), m.group(1)), text)
|
||||||
|
out = _HOUSE.sub(lambda m: f"{m.group(1)} house", out)
|
||||||
|
for k, v in _WORDS.items():
|
||||||
|
out = out.replace(k, v)
|
||||||
|
return out
|
||||||
@@ -13,6 +13,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from typing import Any, Protocol
|
from typing import Any, Protocol
|
||||||
|
|
||||||
|
from app.abbreviations import expand
|
||||||
from app.engine.formats import SIGN_ABBR, SIGNS
|
from app.engine.formats import SIGN_ABBR, SIGNS
|
||||||
|
|
||||||
PLANET_ABBR = {
|
PLANET_ABBR = {
|
||||||
@@ -38,11 +39,13 @@ def _effect(row: dict) -> str:
|
|||||||
|
|
||||||
def _is_noise(sig: str, effect: str) -> bool:
|
def _is_noise(sig: str, effect: str) -> bool:
|
||||||
s = sig.strip().lower()
|
s = sig.strip().lower()
|
||||||
|
e = effect.strip().lower()
|
||||||
return (
|
return (
|
||||||
not effect
|
e in ("", "nan", "x", "x?", "?", "-") # efekt pusty/zastępczy
|
||||||
or s.startswith("significator")
|
or s.startswith("significator") # wiersz-legenda/nagłówek
|
||||||
or "header" in s
|
or "header" in s
|
||||||
or s in ("x", "x?", "nan")
|
or s.startswith("*") # *MARKER / *header
|
||||||
|
or s in ("x", "x?", "nan") # znacznik „pomiń rekord"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -65,7 +68,7 @@ def _facet_samples(rows: list[dict], token: str, limit: int = 4) -> list[dict]:
|
|||||||
eff = _effect(r)
|
eff = _effect(r)
|
||||||
if _is_noise(sig, eff):
|
if _is_noise(sig, eff):
|
||||||
continue
|
continue
|
||||||
out.append({"significator": sig.strip(), "effect": eff})
|
out.append({"significator": sig.strip(), "expanded": expand(sig.strip()), "effect": eff})
|
||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
"""Testy rozwijania skrótów sygnifikatorów."""
|
||||||
|
from app.abbreviations import expand
|
||||||
|
|
||||||
|
|
||||||
|
def test_planet_in_sign():
|
||||||
|
assert expand("[Su in [Tau") == "Sun in Taurus"
|
||||||
|
|
||||||
|
|
||||||
|
def test_aspect_and_house():
|
||||||
|
assert expand("[Sa [conj [Su in 6th H.") == "Saturn conjunction Sun in 6th house"
|
||||||
|
|
||||||
|
|
||||||
|
def test_affliction_word_and_house():
|
||||||
|
assert expand("[Ne affl. in the 7th H.") == "Neptune afflicted in the 7th house"
|
||||||
|
|
||||||
|
|
||||||
|
def test_unknown_token_kept_without_bracket():
|
||||||
|
assert expand("[Xyz rising") == "Xyz rising"
|
||||||
|
|
||||||
|
|
||||||
|
def test_empty_passthrough():
|
||||||
|
assert expand("") == ""
|
||||||
@@ -25,6 +25,7 @@ def test_sign_and_house_facets():
|
|||||||
facets = {f["type"]: f for f in item["facets"]}
|
facets = {f["type"]: f for f in item["facets"]}
|
||||||
assert facets["sign"]["count"] == 1
|
assert facets["sign"]["count"] == 1
|
||||||
assert facets["sign"]["samples"][0]["effect"] == "efekt znak"
|
assert facets["sign"]["samples"][0]["effect"] == "efekt znak"
|
||||||
|
assert facets["sign"]["samples"][0]["expanded"] == "Sun in Taurus" # rozwinięcie skrótu
|
||||||
assert facets["house"]["count"] == 1
|
assert facets["house"]["count"] == 1
|
||||||
assert facets["house"]["token"] == "11th H."
|
assert facets["house"]["token"] == "11th H."
|
||||||
assert facets["house"]["samples"][0]["effect"] == "efekt dom"
|
assert facets["house"]["samples"][0]["effect"] == "efekt dom"
|
||||||
|
|||||||
@@ -61,3 +61,4 @@ tr:last-child td { border-bottom: none; }
|
|||||||
.samples td.nowrap { color: var(--accent); padding-right: 1rem; }
|
.samples td.nowrap { color: var(--accent); padding-right: 1rem; }
|
||||||
.facet { margin: .4rem 0 .6rem 1rem; }
|
.facet { margin: .4rem 0 .6rem 1rem; }
|
||||||
.facet-head { color: var(--ink); font-size: .9rem; }
|
.facet-head { color: var(--ink); font-size: .9rem; }
|
||||||
|
.samples td.sig { color: var(--accent); padding-right: 1rem; cursor: help; }
|
||||||
|
|||||||
@@ -56,7 +56,7 @@
|
|||||||
<table class="samples">
|
<table class="samples">
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for s in f.samples %}
|
{% for s in f.samples %}
|
||||||
<tr><td class="mono nowrap">{{ s.significator }}</td><td>{{ s.effect }}</td></tr>
|
<tr><td class="sig nowrap" title="{{ s.significator }}">{{ s.expanded }}</td><td>{{ s.effect }}</td></tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
Reference in New Issue
Block a user