xor_tanakh_2 / build_indices.py
neuralworm's picture
initial commit
f054e62
import json
import logging
import re
import os
from collections import defaultdict
import pickle
import time
import shutil
from gematria import calculate_gematria
# --- Konfiguration ---
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
BOOK_RANGE = range(1, 40)
MAX_PHRASE_WORDS = 20
TEXTS_DIR = "texts/torah"
CACHE_FILE = "tanakh_phrasedict.cache"
OLD_INDICES_DIR = "indices_by_book"
def clean_text(text):
"""Bereinigt den hebräischen Text."""
text = re.sub(r'\[.*?\]', '', text)
text = re.sub(r"[^\u05D0-\u05EA\s]+", "", text)
text = re.sub(r"\s+", " ", text).strip()
return text
def cleanup_old_files():
"""Löscht alte, inkompatible Dateien und Verzeichnisse."""
if os.path.isdir(OLD_INDICES_DIR):
logging.warning(f"Lösche altes Index-Verzeichnis: '{OLD_INDICES_DIR}'...")
shutil.rmtree(OLD_INDICES_DIR)
# Die alte Cache-Datei muss ebenfalls gelöscht werden, da sie das neue Format nicht hat
if os.path.exists(CACHE_FILE):
logging.warning(f"Lösche alte Cache-Datei für Re-Indizierung: '{CACHE_FILE}'...")
os.remove(CACHE_FILE)
def main():
"""Erstellt ein globales Phrasen-Wörterbuch mit Wortanzahl und Frequenz."""
logging.info("Starte den globalen Index-Builder...")
start_time = time.time()
temp_phrases = []
phrase_frequencies = defaultdict(int)
# --- Phase 1: Alle Phrasen sammeln und Frequenzen zählen ---
logging.info("Phase 1: Sammle Phrasen und zähle Frequenzen...")
for book_num in BOOK_RANGE:
filepath = os.path.join(TEXTS_DIR, f"{book_num:02}.json")
if not os.path.exists(filepath):
continue
logging.info(f" -> Verarbeite Buch {book_num:02}...")
with open(filepath, 'r', encoding='utf-8') as f:
data = json.load(f)
for chap_idx, chapter in enumerate(data.get("text", []), start=1):
for verse_idx, verse_text in enumerate(chapter, start=1):
words = clean_text(verse_text).split()
if not words:
continue
for length in range(1, min(len(words), MAX_PHRASE_WORDS) + 1):
for start in range(len(words) - length + 1):
phrase_words = words[start:start+length]
phrase_text = " ".join(phrase_words)
gematria_val = calculate_gematria("".join(phrase_words))
if gematria_val > 0:
source_ref = f"B{book_num:02d},K{chap_idx:02d},V{verse_idx:02d}"
# Speichere alle relevanten Daten temporär
temp_phrases.append({
"gematria": gematria_val,
"text": phrase_text,
"source": source_ref,
"words": length
})
# Zähle die Häufigkeit jeder einzigartigen Phrase
phrase_frequencies[phrase_text] += 1
logging.info(f"Phase 1 abgeschlossen. {len(temp_phrases):,} Phrasen-Instanzen gefunden.")
# --- Phase 2: Finales Wörterbuch mit Frequenzdaten erstellen ---
logging.info("Phase 2: Erstelle finales Phrasen-Wörterbuch...")
final_phrase_dict = defaultdict(list)
# Set, um Duplikate (gleiche Phrase, gleiche Gematria) zu vermeiden
seen_phrases = set()
for phrase in temp_phrases:
# Einzigartiger Schlüssel, um zu verhindern, dass die gleiche Phrase mehrfach pro Gematria-Wert gespeichert wird
phrase_key = (phrase['gematria'], phrase['text'])
if phrase_key in seen_phrases:
continue
seen_phrases.add(phrase_key)
final_phrase_dict[phrase['gematria']].append({
"text": phrase['text'],
# Wichtig: Wir speichern jetzt auch Wortanzahl und Frequenz!
"words": phrase['words'],
"freq": phrase_frequencies[phrase['text']],
"source": phrase['source'] # Quelle der ersten Begegnung
})
logging.info("Phase 2 abgeschlossen.")
# --- Phase 3: Speichern ---
logging.info(f"Phase 3: Speichere das Phrasen-Wörterbuch in Cache-Datei: {CACHE_FILE}")
with open(CACHE_FILE, 'wb') as f:
pickle.dump(dict(final_phrase_dict), f)
end_time = time.time()
logging.info(f"\nIndizierung erfolgreich abgeschlossen. Gesamtdauer: {(end_time - start_time):.2f} Sekunden.")
if __name__ == "__main__":
cleanup_old_files()
main()