OPEN SOURCE
software/scripts/evaluate_translations.py
Read on this site and download the files you need.
Nichijoyaku was created using AI. A complete review by human biblical-language and biblical-studies specialists has not been established. Read alongside established translations and original-language resources.
← Back to the open-source guide
1"""Script to evaluate existing translations.23This script generates evaluation prompts for translations.4Since the user has Claude Max subscription, the evaluations5can be performed directly by Claude in conversation.67Usage:8# Generate evaluation prompt for a verse9uv run python scripts/evaluate_translations.py titus 1 11011# Generate prompts for entire chapter12uv run python scripts/evaluate_translations.py titus 11314# Show evaluation summary for a book15uv run python scripts/evaluate_translations.py --summary titus1617# Show flagged verses18uv run python scripts/evaluate_translations.py --flagged titus19"""2021from __future__ import annotations2223import argparse24import json25import sys26from pathlib import Path2728from src.context.builder import ContextBuilder29from src.context.glossary import GlossaryManager30from src.data.loader import DataLoader31from src.evaluation.evaluator import TranslationEvaluator, build_evaluation_prompt32from src.evaluation.storage import EvaluationStorage33from src.models.verse import VerseReference343536def load_translation(data_dir: Path, book: str, chapter: int, verse: int) -> str | None:37"""Load a translation from the output files."""38chapter_file = data_dir / "output" / book / f"chapter_{chapter:02d}.json"39if not chapter_file.exists():40return None4142with chapter_file.open("r", encoding="utf-8") as f:43data = json.load(f)4445verses = data.get("verses", {})46verse_data = verses.get(str(verse))47if verse_data:48return verse_data.get("text")49return None505152def generate_verse_prompt(53data_dir: Path, book: str, chapter: int, verse: int54) -> str | None:55"""Generate an evaluation prompt for a single verse."""56loader = DataLoader(data_dir)57glossary = GlossaryManager(loader.load_glossary())58context_builder = ContextBuilder(loader, glossary)5960# Load the translation61translation = load_translation(data_dir, book, chapter, verse)62if not translation:63print(f"No translation found for {book}:{chapter}:{verse}", file=sys.stderr)64return None6566# Build context67ref = VerseReference(book=book, chapter=chapter, verse=verse)68context = context_builder.build_context(ref)6970# Build prompt71evaluator = TranslationEvaluator()72return evaluator.build_verse_prompt(translation, context)737475def generate_chapter_prompts(data_dir: Path, book: str, chapter: int) -> list[dict]:76"""Generate evaluation prompts for all verses in a chapter."""77loader = DataLoader(data_dir)7879# Get verse count80chapter_file = data_dir / "output" / book / f"chapter_{chapter:02d}.json"81if not chapter_file.exists():82print(f"No translations found for {book} chapter {chapter}", file=sys.stderr)83return []8485with chapter_file.open("r", encoding="utf-8") as f:86data = json.load(f)8788verses = data.get("verses", {})89prompts = []9091for verse_num_str in sorted(verses.keys(), key=int):92verse_num = int(verse_num_str)93translation = verses[verse_num_str].get("text")94if translation:95prompt = generate_verse_prompt(data_dir, book, chapter, verse_num)96if prompt:97prompts.append(98{99"reference": f"{book}:{chapter}:{verse_num}",100"translation": translation,101"prompt": prompt,102}103)104105return prompts106107108def show_summary(data_dir: Path, book: str) -> None:109"""Show evaluation summary for a book."""110storage = EvaluationStorage(data_dir)111summary = storage.get_book_summary(book)112113if not summary:114print(f"No evaluations found for {book}")115return116117print(f"\n{'='*60}")118print(f"Evaluation Summary: {book.upper()}")119print(f"{'='*60}")120print(f"Chapters evaluated: {summary.total_chapters}")121print(f"Verses evaluated: {summary.total_verses}")122print(f"Overall score: {summary.overall_score}%")123print(f"\nDimension Scores:")124for dim, score in sorted(summary.aggregate_scores.items()):125print(f" {dim}: {score}%")126print(f"\nFlagged verses: {len(summary.flagged_verses)}")127if summary.flagged_verses:128for ref in summary.flagged_verses[:10]: # Show first 10129print(f" - {ref}")130if len(summary.flagged_verses) > 10:131print(f" ... and {len(summary.flagged_verses) - 10} more")132133134def show_flagged(data_dir: Path, book: str) -> None:135"""Show all flagged verses for a book."""136storage = EvaluationStorage(data_dir)137flagged = storage.get_flagged_verses(book)138139if not flagged:140print(f"No flagged verses for {book}")141return142143print(f"\nFlagged verses in {book}:")144for ref in flagged:145# Load evaluation to get flags146chapter_eval = storage.load_chapter_evaluation(ref.book, ref.chapter)147if chapter_eval and ref.verse in chapter_eval.verses:148verse_eval = chapter_eval.verses[ref.verse]149flags = ", ".join(verse_eval.flags)150print(f" {ref.book}:{ref.chapter}:{ref.verse} - [{flags}]")151152153def main() -> None:154"""Main entry point."""155parser = argparse.ArgumentParser(156description="Generate evaluation prompts for translations"157)158parser.add_argument("book", nargs="?", help="Book name (e.g., 'titus')")159parser.add_argument("chapter", nargs="?", type=int, help="Chapter number")160parser.add_argument("verse", nargs="?", type=int, help="Verse number (optional)")161parser.add_argument(162"--summary", action="store_true", help="Show evaluation summary for book"163)164parser.add_argument(165"--flagged", action="store_true", help="Show flagged verses for book"166)167parser.add_argument(168"--data-dir", default="data", help="Data directory (default: data)"169)170171args = parser.parse_args()172data_dir = Path(args.data_dir)173174if args.summary:175if not args.book:176print("Error: book name required for --summary", file=sys.stderr)177sys.exit(1)178show_summary(data_dir, args.book)179return180181if args.flagged:182if not args.book:183print("Error: book name required for --flagged", file=sys.stderr)184sys.exit(1)185show_flagged(data_dir, args.book)186return187188if not args.book or not args.chapter:189parser.print_help()190sys.exit(1)191192if args.verse:193# Single verse194prompt = generate_verse_prompt(data_dir, args.book, args.chapter, args.verse)195if prompt:196print(prompt)197else:198# Entire chapter199prompts = generate_chapter_prompts(data_dir, args.book, args.chapter)200print(json.dumps(prompts, ensure_ascii=False, indent=2))201202203if __name__ == "__main__":204main()205