From 2e8c2c11d09fe1bfc70f70760233d09d02ef796a Mon Sep 17 00:00:00 2001 From: local Date: Sun, 8 Feb 2026 01:57:44 +0000 Subject: [PATCH] Add persian-tutor: Gradio-based GCSE Persian language learning app Vocabulary study with FSRS spaced repetition, AI tutoring (Ollama/Claude), essay marking, idioms browser, Anki export, and dashboard. 918 vocabulary entries across 39 categories. 41 tests passing. Co-Authored-By: Claude Opus 4.6 --- python/persian-tutor/CLAUDE.md | 38 + python/persian-tutor/README.md | 57 + python/persian-tutor/ai.py | 44 + python/persian-tutor/anki_export.py | 76 + python/persian-tutor/app.py | 511 ++ python/persian-tutor/data/vocabulary.json | 7346 +++++++++++++++++ python/persian-tutor/db.py | 234 + python/persian-tutor/modules/__init__.py | 0 python/persian-tutor/modules/dashboard.py | 84 + python/persian-tutor/modules/essay.py | 78 + python/persian-tutor/modules/idioms.py | 200 + python/persian-tutor/modules/tutor.py | 65 + python/persian-tutor/modules/vocab.py | 152 + python/persian-tutor/requirements.txt | 3 + python/persian-tutor/scripts/build_vocab.py | 1100 +++ .../persian-tutor/scripts/generate_vocab.py | 81 + python/persian-tutor/stt.py | 65 + python/persian-tutor/tests/__init__.py | 0 python/persian-tutor/tests/test_ai.py | 89 + .../persian-tutor/tests/test_anki_export.py | 86 + python/persian-tutor/tests/test_db.py | 151 + python/persian-tutor/tests/test_vocab.py | 204 + 22 files changed, 10664 insertions(+) create mode 100644 python/persian-tutor/CLAUDE.md create mode 100644 python/persian-tutor/README.md create mode 100644 python/persian-tutor/ai.py create mode 100644 python/persian-tutor/anki_export.py create mode 100644 python/persian-tutor/app.py create mode 100644 python/persian-tutor/data/vocabulary.json create mode 100644 python/persian-tutor/db.py create mode 100644 python/persian-tutor/modules/__init__.py create mode 100644 python/persian-tutor/modules/dashboard.py create mode 100644 python/persian-tutor/modules/essay.py create mode 100644 python/persian-tutor/modules/idioms.py create mode 100644 python/persian-tutor/modules/tutor.py create mode 100644 python/persian-tutor/modules/vocab.py create mode 100644 python/persian-tutor/requirements.txt create mode 100644 python/persian-tutor/scripts/build_vocab.py create mode 100644 python/persian-tutor/scripts/generate_vocab.py create mode 100644 python/persian-tutor/stt.py create mode 100644 python/persian-tutor/tests/__init__.py create mode 100644 python/persian-tutor/tests/test_ai.py create mode 100644 python/persian-tutor/tests/test_anki_export.py create mode 100644 python/persian-tutor/tests/test_db.py create mode 100644 python/persian-tutor/tests/test_vocab.py diff --git a/python/persian-tutor/CLAUDE.md b/python/persian-tutor/CLAUDE.md new file mode 100644 index 0000000..71bf151 --- /dev/null +++ b/python/persian-tutor/CLAUDE.md @@ -0,0 +1,38 @@ +# Persian Language Tutor + +## Overview +Gradio-based Persian (Farsi) language learning app for English speakers, using GCSE Persian vocabulary (Pearson spec) as seed data. + +## Tech Stack +- **Frontend**: Gradio (browser handles RTL natively) +- **Spaced repetition**: py-fsrs (same algorithm as Anki) +- **AI**: Ollama (fast, local) + Claude CLI (smart, subprocess) +- **STT**: faster-whisper via sttlib from tool-speechtotext +- **Anki export**: genanki for .apkg generation +- **Database**: SQLite (file-based, data/progress.db) +- **Environment**: `whisper-ollama` conda env + +## Running +```bash +mamba run -n whisper-ollama python app.py +``` + +## Testing +```bash +mamba run -n whisper-ollama python -m pytest tests/ +``` + +## Key Paths +- `data/vocabulary.json` — GCSE vocabulary data +- `data/progress.db` — SQLite database (auto-created) +- `app.py` — Gradio entry point +- `db.py` — Database layer with FSRS integration +- `ai.py` — Dual AI backend (Ollama + Claude) +- `stt.py` — Persian speech-to-text wrapper +- `modules/` — Feature modules (vocab, dashboard, essay, tutor, idioms) + +## Architecture +- Single-process Gradio app with shared SQLite connection +- FSRS Card objects serialized as JSON in SQLite TEXT columns +- Timestamps stored as ISO-8601 strings +- sttlib imported via sys.path from tool-speechtotext project diff --git a/python/persian-tutor/README.md b/python/persian-tutor/README.md new file mode 100644 index 0000000..76667ee --- /dev/null +++ b/python/persian-tutor/README.md @@ -0,0 +1,57 @@ +# Persian Language Tutor + +A Gradio-based Persian (Farsi) language learning app for English speakers, built around GCSE Persian vocabulary (Pearson specification). + +## Features + +- **Vocabulary Study** — Search, browse, and study 918 GCSE Persian words across 39 categories +- **Flashcards with FSRS** — Spaced repetition scheduling (same algorithm as Anki) +- **Idioms & Expressions** — 25 Persian social conventions with cultural context +- **AI Tutor** — Conversational Persian lessons by GCSE theme (via Ollama) +- **Essay Marking** — Write Persian essays, get AI feedback and grading (via Claude) +- **Dashboard** — Track progress, streaks, and mastery +- **Anki Export** — Generate .apkg decks for offline study +- **Voice Input** — Speak Persian via microphone (Whisper STT) in the Tutor tab + +## Prerequisites + +- `whisper-ollama` conda environment with Python 3.10+ +- Ollama running locally with `qwen2.5:7b` (or another model) +- Claude CLI installed (for essay marking / smart mode) + +## Setup + +```bash +/home/ys/miniforge3/envs/whisper-ollama/bin/pip install gradio genanki fsrs +``` + +## Running the app + +```bash +cd /home/ys/family-repo/Code/python/persian-tutor +/home/ys/miniforge3/envs/whisper-ollama/bin/python app.py +``` + +Then open http://localhost:7860 in your browser. + +## Running tests + +```bash +cd /home/ys/family-repo/Code/python/persian-tutor +/home/ys/miniforge3/envs/whisper-ollama/bin/python -m pytest tests/ -v +``` + +41 tests covering db, vocab, ai, and anki_export modules. + +## Expanding vocabulary + +The vocabulary can be expanded by editing `data/vocabulary.json` directly or by updating `scripts/build_vocab.py` and re-running it: + +```bash +/home/ys/miniforge3/envs/whisper-ollama/bin/python scripts/build_vocab.py +``` + +## TODO + +- [ ] Voice-based vocabulary testing — answer flashcard prompts by speaking Persian +- [ ] Improved UI theme and layout polish diff --git a/python/persian-tutor/ai.py b/python/persian-tutor/ai.py new file mode 100644 index 0000000..c6b6240 --- /dev/null +++ b/python/persian-tutor/ai.py @@ -0,0 +1,44 @@ +"""Dual AI backend: Ollama (fast/local) and Claude CLI (smart).""" + +import subprocess + +import ollama + +DEFAULT_OLLAMA_MODEL = "qwen2.5:7b" + + +def ask_ollama(prompt, system=None, model=DEFAULT_OLLAMA_MODEL): + """Query Ollama with an optional system prompt.""" + messages = [] + if system: + messages.append({"role": "system", "content": system}) + messages.append({"role": "user", "content": prompt}) + response = ollama.chat(model=model, messages=messages) + return response.message.content + + +def ask_claude(prompt): + """Query Claude via the CLI subprocess.""" + result = subprocess.run( + ["claude", "-p", prompt], + capture_output=True, + text=True, + ) + return result.stdout.strip() + + +def ask(prompt, system=None, quality="fast"): + """Unified interface. quality='fast' uses Ollama, 'smart' uses Claude.""" + if quality == "smart": + return ask_claude(prompt) + return ask_ollama(prompt, system=system) + + +def chat_ollama(messages, system=None, model=DEFAULT_OLLAMA_MODEL): + """Multi-turn conversation with Ollama.""" + all_messages = [] + if system: + all_messages.append({"role": "system", "content": system}) + all_messages.extend(messages) + response = ollama.chat(model=model, messages=all_messages) + return response.message.content diff --git a/python/persian-tutor/anki_export.py b/python/persian-tutor/anki_export.py new file mode 100644 index 0000000..676762e --- /dev/null +++ b/python/persian-tutor/anki_export.py @@ -0,0 +1,76 @@ +"""Generate Anki .apkg decks from vocabulary data.""" + +import genanki +import random + +# Stable model/deck IDs (generated once, kept constant) +_MODEL_ID = 1607392319 +_DECK_ID = 2059400110 + + +def _make_model(): + """Create an Anki note model with two card templates.""" + return genanki.Model( + _MODEL_ID, + "GCSE Persian", + fields=[ + {"name": "English"}, + {"name": "Persian"}, + {"name": "Finglish"}, + {"name": "Category"}, + ], + templates=[ + { + "name": "English → Persian", + "qfmt": '
{{English}}
' + '
{{Category}}', + "afmt": '{{FrontSide}}
' + '
{{Persian}}
' + "
{{Finglish}}
", + }, + { + "name": "Persian → English", + "qfmt": '
{{Persian}}
' + '
{{Category}}', + "afmt": '{{FrontSide}}
' + '
{{English}}
' + "
{{Finglish}}
", + }, + ], + css=".card { font-family: arial; text-align: center; }", + ) + + +def export_deck(vocab, categories=None, output_path="gcse-persian.apkg"): + """Generate an Anki .apkg deck from vocabulary entries. + + Args: + vocab: List of vocabulary entries (dicts with english, persian, finglish, category). + categories: Optional list of categories to include. None = all. + output_path: Where to save the .apkg file. + + Returns: + Path to the generated .apkg file. + """ + model = _make_model() + deck = genanki.Deck(_DECK_ID, "GCSE Persian") + + for entry in vocab: + if categories and entry.get("category") not in categories: + continue + + note = genanki.Note( + model=model, + fields=[ + entry.get("english", ""), + entry.get("persian", ""), + entry.get("finglish", ""), + entry.get("category", ""), + ], + guid=genanki.guid_for(entry.get("id", entry["english"])), + ) + deck.add_note(note) + + package = genanki.Package(deck) + package.write_to_file(output_path) + return output_path diff --git a/python/persian-tutor/app.py b/python/persian-tutor/app.py new file mode 100644 index 0000000..fa06192 --- /dev/null +++ b/python/persian-tutor/app.py @@ -0,0 +1,511 @@ +"""Persian Language Tutor — Gradio UI.""" + +import json +import os +import tempfile +import time + +import gradio as gr + +import db +from modules import vocab, dashboard, essay, tutor, idioms +from modules.essay import GCSE_THEMES +from modules.tutor import THEME_PROMPTS +from anki_export import export_deck + + +# ---------- Initialise ---------- +db.init_db() +vocabulary = vocab.load_vocab() +categories = ["All"] + vocab.get_categories() + + +# ---------- Helper ---------- +def _rtl(text, size="2em"): + return f'
{text}
' + + +# ================================================================ +# TAB HANDLERS +# ================================================================ + +# ---------- Dashboard ---------- +def refresh_dashboard(): + overview_md = dashboard.format_overview_markdown() + cat_data = dashboard.get_category_breakdown() + quiz_data = dashboard.get_recent_quizzes() + return overview_md, cat_data, quiz_data + + +# ---------- Vocabulary Search ---------- +def do_search(query, category): + results = vocab.search(query) + if category and category != "All": + results = [r for r in results if r["category"] == category] + if not results: + return "No results found." + lines = [] + for r in results: + status = vocab.get_word_status(r["id"]) + icon = {"new": "⬜", "learning": "🟨", "mastered": "🟩"}.get(status, "⬜") + lines.append( + f'{icon} **{r["english"]}** — ' + f'{r["persian"]}' + f' ({r.get("finglish", "")})' + ) + return "\n\n".join(lines) + + +def do_random_word(category, transliteration): + entry = vocab.get_random_word(category=category) + if not entry: + return "No words found." + return vocab.format_word_card(entry, show_transliteration=transliteration) + + +# ---------- Flashcards ---------- +def start_flashcards(category, direction): + batch = vocab.get_flashcard_batch(count=10, category=category) + if not batch: + return "No words available.", [], 0, 0, "", gr.update(visible=False) + + first = batch[0] + if direction == "English → Persian": + prompt = f'
{first["english"]}
' + else: + prompt = _rtl(first["persian"]) + + return ( + prompt, # card_display + batch, # batch state + 0, # current index + 0, # score + "", # answer_box cleared + gr.update(visible=True), # answer_area visible + ) + + +def submit_answer(user_answer, batch, index, score, direction, transliteration): + if not batch or index >= len(batch): + return "Session complete!", batch, index, score, "", gr.update(visible=False), "" + + entry = batch[index] + dir_key = "en_to_fa" if direction == "English → Persian" else "fa_to_en" + is_correct, correct_answer, _ = vocab.check_answer(entry["id"], user_answer, direction=dir_key) + + if is_correct: + score += 1 + result = "✅ **Correct!**" + else: + result = f"❌ **Incorrect.** The answer is: " + if dir_key == "en_to_fa": + result += f'{correct_answer}' + else: + result += correct_answer + + card_info = vocab.format_word_card(entry, show_transliteration=transliteration) + feedback = f"{result}\n\n{card_info}\n\n---\n*Rate your recall to continue:*" + + return feedback, batch, index, score, "", gr.update(visible=True), "" + + +def rate_and_next(rating_str, batch, index, score, direction): + if not batch or index >= len(batch): + return "Session complete!", batch, index, score, gr.update(visible=False) + + import fsrs as fsrs_mod + rating_map = { + "Again": fsrs_mod.Rating.Again, + "Hard": fsrs_mod.Rating.Hard, + "Good": fsrs_mod.Rating.Good, + "Easy": fsrs_mod.Rating.Easy, + } + rating = rating_map.get(rating_str, fsrs_mod.Rating.Good) + entry = batch[index] + db.update_word_progress(entry["id"], rating) + + index += 1 + if index >= len(batch): + summary = f"## Session Complete!\n\n**Score:** {score}/{len(batch)}\n\n" + summary += f"**Accuracy:** {score/len(batch)*100:.0f}%" + return summary, batch, index, score, gr.update(visible=False) + + next_entry = batch[index] + if direction == "English → Persian": + prompt = f'
{next_entry["english"]}
' + else: + prompt = _rtl(next_entry["persian"]) + + return prompt, batch, index, score, gr.update(visible=True) + + +# ---------- Idioms ---------- +def show_random_idiom(transliteration): + expr = idioms.get_random_expression() + return idioms.format_expression(expr, show_transliteration=transliteration), expr + + +def explain_idiom(expr_state): + if not expr_state: + return "Pick an idiom first." + return idioms.explain_expression(expr_state) + + +def browse_idioms(transliteration): + exprs = idioms.get_all_expressions() + lines = [] + for e in exprs: + line = f'**{e["persian"]}** — {e["english"]}' + if transliteration != "off": + line += f' *({e["finglish"]})*' + lines.append(line) + return "\n\n".join(lines) + + +# ---------- Tutor ---------- +def start_tutor_lesson(theme): + response, messages, system = tutor.start_lesson(theme) + chat_history = [{"role": "assistant", "content": response}] + return chat_history, messages, system, time.time() + + +def send_tutor_message(user_msg, chat_history, messages, system, audio_input): + # Use STT if audio provided and no text + if audio_input is not None and (not user_msg or not user_msg.strip()): + try: + from stt import transcribe_persian + user_msg = transcribe_persian(audio_input) + except Exception: + user_msg = "" + + if not user_msg or not user_msg.strip(): + return chat_history, messages, "", None + + response, messages = tutor.process_response(user_msg, messages, system=system) + chat_history.append({"role": "user", "content": user_msg}) + chat_history.append({"role": "assistant", "content": response}) + return chat_history, messages, "", None + + +def save_tutor(theme, messages, start_time): + if messages and len(messages) > 1: + tutor.save_session(theme, messages, start_time) + return "Session saved!" + return "Nothing to save." + + +# ---------- Essay ---------- +def submit_essay(text, theme): + if not text or not text.strip(): + return "Please write an essay first." + return essay.mark_essay(text, theme) + + +def load_essay_history(): + return essay.get_essay_history() + + +# ---------- Settings / Export ---------- +def do_anki_export(cats_selected): + v = vocab.load_vocab() + cats = cats_selected if cats_selected else None + path = os.path.join(tempfile.gettempdir(), "gcse-persian.apkg") + export_deck(v, categories=cats, output_path=path) + return path + + +def reset_progress(): + conn = db.get_connection() + conn.execute("DELETE FROM word_progress") + conn.execute("DELETE FROM quiz_sessions") + conn.execute("DELETE FROM essays") + conn.execute("DELETE FROM tutor_sessions") + conn.commit() + return "Progress reset." + + +# ================================================================ +# GRADIO UI +# ================================================================ + +with gr.Blocks(title="Persian Language Tutor") as app: + gr.Markdown("# 🇮🇷 Persian Language Tutor\n*GCSE Persian vocabulary with spaced repetition*") + + # Shared state + transliteration_state = gr.State(value="Finglish") + + with gr.Tabs(): + # ==================== DASHBOARD ==================== + with gr.Tab("📊 Dashboard"): + overview_md = gr.Markdown("Loading...") + with gr.Row(): + cat_table = gr.Dataframe( + headers=["Category", "Total", "Seen", "Mastered", "Progress"], + label="Category Breakdown", + ) + quiz_table = gr.Dataframe( + headers=["Date", "Category", "Score", "Duration"], + label="Recent Quizzes", + ) + refresh_btn = gr.Button("Refresh", variant="secondary") + refresh_btn.click( + fn=refresh_dashboard, + outputs=[overview_md, cat_table, quiz_table], + ) + + # ==================== VOCABULARY ==================== + with gr.Tab("📚 Vocabulary"): + with gr.Row(): + search_box = gr.Textbox( + label="Search (English or Persian)", + placeholder="Type to search...", + ) + vocab_cat = gr.Dropdown( + choices=categories, value="All", label="Category" + ) + search_btn = gr.Button("Search", variant="primary") + random_btn = gr.Button("Random Word") + search_results = gr.Markdown("Search for a word above.") + + search_btn.click( + fn=do_search, + inputs=[search_box, vocab_cat], + outputs=[search_results], + ) + search_box.submit( + fn=do_search, + inputs=[search_box, vocab_cat], + outputs=[search_results], + ) + random_btn.click( + fn=do_random_word, + inputs=[vocab_cat, transliteration_state], + outputs=[search_results], + ) + + # ==================== FLASHCARDS ==================== + with gr.Tab("🃏 Flashcards"): + with gr.Row(): + fc_category = gr.Dropdown( + choices=categories, value="All", label="Category" + ) + fc_direction = gr.Radio( + ["English → Persian", "Persian → English"], + value="English → Persian", + label="Direction", + ) + start_fc_btn = gr.Button("Start Session", variant="primary") + + card_display = gr.Markdown("Press 'Start Session' to begin.") + + # Hidden states + fc_batch = gr.State([]) + fc_index = gr.State(0) + fc_score = gr.State(0) + + with gr.Group(visible=False) as answer_area: + answer_box = gr.Textbox( + label="Your answer", + placeholder="Type your answer...", + rtl=True, + ) + submit_ans_btn = gr.Button("Submit Answer", variant="primary") + answer_feedback = gr.Markdown("") + + with gr.Row(): + btn_again = gr.Button("Again", variant="stop") + btn_hard = gr.Button("Hard", variant="secondary") + btn_good = gr.Button("Good", variant="primary") + btn_easy = gr.Button("Easy", variant="secondary") + + start_fc_btn.click( + fn=start_flashcards, + inputs=[fc_category, fc_direction], + outputs=[card_display, fc_batch, fc_index, fc_score, answer_box, answer_area], + ) + + submit_ans_btn.click( + fn=submit_answer, + inputs=[answer_box, fc_batch, fc_index, fc_score, fc_direction, transliteration_state], + outputs=[card_display, fc_batch, fc_index, fc_score, answer_box, answer_area, answer_feedback], + ) + answer_box.submit( + fn=submit_answer, + inputs=[answer_box, fc_batch, fc_index, fc_score, fc_direction, transliteration_state], + outputs=[card_display, fc_batch, fc_index, fc_score, answer_box, answer_area, answer_feedback], + ) + + for btn, label in [(btn_again, "Again"), (btn_hard, "Hard"), (btn_good, "Good"), (btn_easy, "Easy")]: + btn.click( + fn=rate_and_next, + inputs=[gr.State(label), fc_batch, fc_index, fc_score, fc_direction], + outputs=[card_display, fc_batch, fc_index, fc_score, answer_area], + ) + + # ==================== IDIOMS ==================== + with gr.Tab("💬 Idioms & Expressions"): + idiom_display = gr.Markdown("Click 'Random Idiom' or browse below.") + idiom_state = gr.State(None) + + with gr.Row(): + random_idiom_btn = gr.Button("Random Idiom", variant="primary") + explain_idiom_btn = gr.Button("Explain Usage") + browse_idiom_btn = gr.Button("Browse All") + + idiom_explanation = gr.Markdown("") + + random_idiom_btn.click( + fn=show_random_idiom, + inputs=[transliteration_state], + outputs=[idiom_display, idiom_state], + ) + explain_idiom_btn.click( + fn=explain_idiom, + inputs=[idiom_state], + outputs=[idiom_explanation], + ) + browse_idiom_btn.click( + fn=browse_idioms, + inputs=[transliteration_state], + outputs=[idiom_display], + ) + + # ==================== TUTOR ==================== + with gr.Tab("🎓 Tutor"): + tutor_theme = gr.Dropdown( + choices=list(THEME_PROMPTS.keys()), + value="Identity and culture", + label="Theme", + ) + start_lesson_btn = gr.Button("New Lesson", variant="primary") + + chatbot = gr.Chatbot(label="Conversation") + + # Tutor states + tutor_messages = gr.State([]) + tutor_system = gr.State("") + tutor_start_time = gr.State(0) + + with gr.Row(): + tutor_input = gr.Textbox( + label="Your message", + placeholder="Type in English or Persian...", + scale=3, + ) + tutor_mic = gr.Audio( + sources=["microphone"], + type="numpy", + label="Speak", + scale=1, + ) + send_btn = gr.Button("Send", variant="primary") + save_btn = gr.Button("Save Session", variant="secondary") + save_status = gr.Markdown("") + + start_lesson_btn.click( + fn=start_tutor_lesson, + inputs=[tutor_theme], + outputs=[chatbot, tutor_messages, tutor_system, tutor_start_time], + ) + + send_btn.click( + fn=send_tutor_message, + inputs=[tutor_input, chatbot, tutor_messages, tutor_system, tutor_mic], + outputs=[chatbot, tutor_messages, tutor_input, tutor_mic], + ) + tutor_input.submit( + fn=send_tutor_message, + inputs=[tutor_input, chatbot, tutor_messages, tutor_system, tutor_mic], + outputs=[chatbot, tutor_messages, tutor_input, tutor_mic], + ) + + save_btn.click( + fn=save_tutor, + inputs=[tutor_theme, tutor_messages, tutor_start_time], + outputs=[save_status], + ) + + # ==================== ESSAY ==================== + with gr.Tab("✍️ Essay"): + essay_theme = gr.Dropdown( + choices=GCSE_THEMES, + value="Identity and culture", + label="Theme", + ) + essay_input = gr.Textbox( + label="Write your essay in Persian", + lines=10, + rtl=True, + placeholder="اینجا بنویسید...", + ) + submit_essay_btn = gr.Button("Submit for Marking", variant="primary") + essay_feedback = gr.Markdown("Write an essay and submit for AI marking.") + + gr.Markdown("### Essay History") + essay_history_table = gr.Dataframe( + headers=["Date", "Theme", "Grade", "Preview"], + label="Past Essays", + ) + refresh_essays_btn = gr.Button("Refresh History") + + submit_essay_btn.click( + fn=submit_essay, + inputs=[essay_input, essay_theme], + outputs=[essay_feedback], + ) + refresh_essays_btn.click( + fn=load_essay_history, + outputs=[essay_history_table], + ) + + # ==================== SETTINGS ==================== + with gr.Tab("⚙️ Settings"): + gr.Markdown("## Settings") + + transliteration_radio = gr.Radio( + ["off", "Finglish", "Academic"], + value="Finglish", + label="Transliteration", + ) + + ollama_model = gr.Textbox( + label="Ollama Model", + value="qwen2.5:7b", + info="Model used for fast AI responses", + ) + + whisper_size = gr.Dropdown( + choices=["tiny", "base", "small", "medium", "large-v3"], + value="medium", + label="Whisper Model Size", + ) + + gr.Markdown("### Anki Export") + export_cats = gr.Dropdown( + choices=vocab.get_categories(), + multiselect=True, + label="Categories to export (empty = all)", + ) + export_btn = gr.Button("Export to Anki (.apkg)", variant="primary") + export_file = gr.File(label="Download") + + export_btn.click(fn=do_anki_export, inputs=[export_cats], outputs=[export_file]) + + gr.Markdown("### Reset") + reset_btn = gr.Button("Reset All Progress", variant="stop") + reset_status = gr.Markdown("") + reset_btn.click(fn=reset_progress, outputs=[reset_status]) + + # Wire transliteration state + transliteration_radio.change( + fn=lambda x: x, + inputs=[transliteration_radio], + outputs=[transliteration_state], + ) + + # Load dashboard on app start + app.load(fn=refresh_dashboard, outputs=[overview_md, cat_table, quiz_table]) + + +if __name__ == "__main__": + app.launch(theme=gr.themes.Soft()) diff --git a/python/persian-tutor/data/vocabulary.json b/python/persian-tutor/data/vocabulary.json new file mode 100644 index 0000000..4c32489 --- /dev/null +++ b/python/persian-tutor/data/vocabulary.json @@ -0,0 +1,7346 @@ +[ + { + "id": "common_verbs_to_accept", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to accept", + "persian": "قبول کردن", + "finglish": "ghabul kardan" + }, + { + "id": "common_verbs_to_achieve", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to achieve", + "persian": "بدست آوردن", + "finglish": "be dast âvardan" + }, + { + "id": "common_verbs_to_add", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to add", + "persian": "اضافه کردن", + "finglish": "ezâfe kardan" + }, + { + "id": "common_verbs_to_agree", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to agree", + "persian": "موافقت کردن", + "finglish": "movâfeghat kardan" + }, + { + "id": "common_verbs_to_allow", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to allow", + "persian": "اجازه دادن", + "finglish": "ejâze dâdan" + }, + { + "id": "common_verbs_to_answer", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to answer", + "persian": "جواب دادن", + "finglish": "javâb dâdan" + }, + { + "id": "common_verbs_to_arrive", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to arrive", + "persian": "رسیدن", + "finglish": "residan" + }, + { + "id": "common_verbs_to_ask", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to ask", + "persian": "پرسیدن", + "finglish": "porsidan" + }, + { + "id": "common_verbs_to_be", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to be", + "persian": "بودن", + "finglish": "budan" + }, + { + "id": "common_verbs_to_become", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to become", + "persian": "شدن", + "finglish": "shodan" + }, + { + "id": "common_verbs_to_begin", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to begin", + "persian": "شروع کردن", + "finglish": "shoru' kardan" + }, + { + "id": "common_verbs_to_believe", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to believe", + "persian": "باور کردن", + "finglish": "bâvar kardan" + }, + { + "id": "common_verbs_to_bring", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to bring", + "persian": "آوردن", + "finglish": "âvardan" + }, + { + "id": "common_verbs_to_build", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to build", + "persian": "ساختن", + "finglish": "sâkhtan" + }, + { + "id": "common_verbs_to_buy", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to buy", + "persian": "خریدن", + "finglish": "kharidan" + }, + { + "id": "common_verbs_to_call", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to call", + "persian": "زنگ زدن", + "finglish": "zang zadan" + }, + { + "id": "common_verbs_to_carry", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to carry", + "persian": "حمل کردن", + "finglish": "haml kardan" + }, + { + "id": "common_verbs_to_catch", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to catch", + "persian": "گرفتن", + "finglish": "gereftan" + }, + { + "id": "common_verbs_to_change", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to change", + "persian": "عوض کردن", + "finglish": "avaz kardan" + }, + { + "id": "common_verbs_to_choose", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to choose", + "persian": "انتخاب کردن", + "finglish": "entekhâb kardan" + }, + { + "id": "common_verbs_to_close", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to close", + "persian": "بستن", + "finglish": "bastan" + }, + { + "id": "common_verbs_to_come", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to come", + "persian": "آمدن", + "finglish": "âmadan" + }, + { + "id": "common_verbs_to_continue", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to continue", + "persian": "ادامه دادن", + "finglish": "edâme dâdan" + }, + { + "id": "common_verbs_to_cook", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to cook", + "persian": "آشپزی کردن", + "finglish": "âshpazi kardan" + }, + { + "id": "common_verbs_to_cost", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to cost", + "persian": "قیمت داشتن", + "finglish": "gheymat dâshtan" + }, + { + "id": "common_verbs_to_count", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to count", + "persian": "شمردن", + "finglish": "shemordan" + }, + { + "id": "common_verbs_to_create", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to create", + "persian": "ایجاد کردن", + "finglish": "ijâd kardan" + }, + { + "id": "common_verbs_to_cross", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to cross", + "persian": "رد شدن", + "finglish": "rad shodan" + }, + { + "id": "common_verbs_to_cry", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to cry", + "persian": "گریه کردن", + "finglish": "gerye kardan" + }, + { + "id": "common_verbs_to_cut", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to cut", + "persian": "بریدن", + "finglish": "boridan" + }, + { + "id": "common_verbs_to_dance", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to dance", + "persian": "رقصیدن", + "finglish": "raghsidan" + }, + { + "id": "common_verbs_to_decide", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to decide", + "persian": "تصمیم گرفتن", + "finglish": "tasmim gereftan" + }, + { + "id": "common_verbs_to_describe", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to describe", + "persian": "توصیف کردن", + "finglish": "tosif kardan" + }, + { + "id": "common_verbs_to_develop", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to develop", + "persian": "توسعه دادن", + "finglish": "tose'e dâdan" + }, + { + "id": "common_verbs_to_die", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to die", + "persian": "مردن", + "finglish": "mordan" + }, + { + "id": "common_verbs_to_do", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to do", + "persian": "انجام دادن", + "finglish": "anjâm dâdan" + }, + { + "id": "common_verbs_to_draw", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to draw", + "persian": "نقاشی کردن", + "finglish": "naghâshi kardan" + }, + { + "id": "common_verbs_to_dream", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to dream", + "persian": "خواب دیدن", + "finglish": "khâb didan" + }, + { + "id": "common_verbs_to_drink", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to drink", + "persian": "نوشیدن", + "finglish": "nushidan" + }, + { + "id": "common_verbs_to_drive", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to drive", + "persian": "رانندگی کردن", + "finglish": "rânandegi kardan" + }, + { + "id": "common_verbs_to_eat", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to eat", + "persian": "خوردن", + "finglish": "khordan" + }, + { + "id": "common_verbs_to_enjoy", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to enjoy", + "persian": "لذت بردن", + "finglish": "lezzat bordan" + }, + { + "id": "common_verbs_to_enter", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to enter", + "persian": "وارد شدن", + "finglish": "vâred shodan" + }, + { + "id": "common_verbs_to_explain", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to explain", + "persian": "توضیح دادن", + "finglish": "tozih dâdan" + }, + { + "id": "common_verbs_to_fall", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to fall", + "persian": "افتادن", + "finglish": "oftâdan" + }, + { + "id": "common_verbs_to_feel", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to feel", + "persian": "احساس کردن", + "finglish": "ehsâs kardan" + }, + { + "id": "common_verbs_to_find", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to find", + "persian": "پیدا کردن", + "finglish": "peydâ kardan" + }, + { + "id": "common_verbs_to_finish", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to finish", + "persian": "تمام کردن", + "finglish": "tamâm kardan" + }, + { + "id": "common_verbs_to_fly", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to fly", + "persian": "پرواز کردن", + "finglish": "parvâz kardan" + }, + { + "id": "common_verbs_to_follow", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to follow", + "persian": "دنبال کردن", + "finglish": "donbâl kardan" + }, + { + "id": "common_verbs_to_forget", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to forget", + "persian": "فراموش کردن", + "finglish": "farâmush kardan" + }, + { + "id": "common_verbs_to_get", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to get", + "persian": "گرفتن", + "finglish": "gereftan" + }, + { + "id": "common_verbs_to_give", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to give", + "persian": "دادن", + "finglish": "dâdan" + }, + { + "id": "common_verbs_to_go", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to go", + "persian": "رفتن", + "finglish": "raftan" + }, + { + "id": "common_verbs_to_grow", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to grow", + "persian": "رشد کردن", + "finglish": "roshd kardan" + }, + { + "id": "common_verbs_to_happen", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to happen", + "persian": "اتفاق افتادن", + "finglish": "ettefâgh oftâdan" + }, + { + "id": "common_verbs_to_hate", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to hate", + "persian": "متنفر بودن", + "finglish": "motenaffer budan" + }, + { + "id": "common_verbs_to_have", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to have", + "persian": "داشتن", + "finglish": "dâshtan" + }, + { + "id": "common_verbs_to_hear", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to hear", + "persian": "شنیدن", + "finglish": "shenidan" + }, + { + "id": "common_verbs_to_help", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to help", + "persian": "کمک کردن", + "finglish": "komak kardan" + }, + { + "id": "common_verbs_to_hold", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to hold", + "persian": "نگه داشتن", + "finglish": "negah dâshtan" + }, + { + "id": "common_verbs_to_hope", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to hope", + "persian": "امیدوار بودن", + "finglish": "omidvâr budan" + }, + { + "id": "common_verbs_to_hurt", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to hurt", + "persian": "درد کردن", + "finglish": "dard kardan" + }, + { + "id": "common_verbs_to_improve", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to improve", + "persian": "بهتر کردن", + "finglish": "behtar kardan" + }, + { + "id": "common_verbs_to_include", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to include", + "persian": "شامل شدن", + "finglish": "shâmel shodan" + }, + { + "id": "common_verbs_to_invite", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to invite", + "persian": "دعوت کردن", + "finglish": "da'vat kardan" + }, + { + "id": "common_verbs_to_join", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to join", + "persian": "پیوستن", + "finglish": "peyvastan" + }, + { + "id": "common_verbs_to_keep", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to keep", + "persian": "نگه داشتن", + "finglish": "negah dâshtan" + }, + { + "id": "common_verbs_to_kill", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to kill", + "persian": "کشتن", + "finglish": "koshtan" + }, + { + "id": "common_verbs_to_know", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to know", + "persian": "دانستن", + "finglish": "dânestan" + }, + { + "id": "common_verbs_to_laugh", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to laugh", + "persian": "خندیدن", + "finglish": "khandidan" + }, + { + "id": "common_verbs_to_learn", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to learn", + "persian": "یاد گرفتن", + "finglish": "yâd gereftan" + }, + { + "id": "common_verbs_to_leave", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to leave", + "persian": "ترک کردن", + "finglish": "tark kardan" + }, + { + "id": "common_verbs_to_let", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to let", + "persian": "اجازه دادن", + "finglish": "ejâze dâdan" + }, + { + "id": "common_verbs_to_like", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to like", + "persian": "دوست داشتن", + "finglish": "dust dâshtan" + }, + { + "id": "common_verbs_to_listen", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to listen", + "persian": "گوش دادن", + "finglish": "gush dâdan" + }, + { + "id": "common_verbs_to_live", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to live", + "persian": "زندگی کردن", + "finglish": "zendegi kardan" + }, + { + "id": "common_verbs_to_look", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to look", + "persian": "نگاه کردن", + "finglish": "negâh kardan" + }, + { + "id": "common_verbs_to_lose", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to lose", + "persian": "از دست دادن", + "finglish": "az dast dâdan" + }, + { + "id": "common_verbs_to_love", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to love", + "persian": "عشق ورزیدن", + "finglish": "eshgh varzidan" + }, + { + "id": "common_verbs_to_make", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to make", + "persian": "درست کردن", + "finglish": "dorost kardan" + }, + { + "id": "common_verbs_to_meet", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to meet", + "persian": "ملاقات کردن", + "finglish": "molâghât kardan" + }, + { + "id": "common_verbs_to_miss", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to miss", + "persian": "دلتنگ بودن", + "finglish": "deltang budan" + }, + { + "id": "common_verbs_to_move", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to move", + "persian": "حرکت کردن", + "finglish": "harekat kardan" + }, + { + "id": "common_verbs_to_need", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to need", + "persian": "نیاز داشتن", + "finglish": "niyâz dâshtan" + }, + { + "id": "common_verbs_to_open", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to open", + "persian": "باز کردن", + "finglish": "bâz kardan" + }, + { + "id": "common_verbs_to_pay", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to pay", + "persian": "پرداخت کردن", + "finglish": "pardâkht kardan" + }, + { + "id": "common_verbs_to_play", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to play", + "persian": "بازی کردن", + "finglish": "bâzi kardan" + }, + { + "id": "common_verbs_to_practise", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to practise", + "persian": "تمرین کردن", + "finglish": "tamrin kardan" + }, + { + "id": "common_verbs_to_prefer", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to prefer", + "persian": "ترجیح دادن", + "finglish": "tarjih dâdan" + }, + { + "id": "common_verbs_to_prepare", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to prepare", + "persian": "آماده کردن", + "finglish": "âmâde kardan" + }, + { + "id": "common_verbs_to_produce", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to produce", + "persian": "تولید کردن", + "finglish": "tolid kardan" + }, + { + "id": "common_verbs_to_promise", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to promise", + "persian": "قول دادن", + "finglish": "ghol dâdan" + }, + { + "id": "common_verbs_to_protect", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to protect", + "persian": "محافظت کردن", + "finglish": "mohâfezat kardan" + }, + { + "id": "common_verbs_to_pull", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to pull", + "persian": "کشیدن", + "finglish": "keshidan" + }, + { + "id": "common_verbs_to_push", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to push", + "persian": "هل دادن", + "finglish": "hol dâdan" + }, + { + "id": "common_verbs_to_put", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to put", + "persian": "گذاشتن", + "finglish": "gozâshtan" + }, + { + "id": "common_verbs_to_rain", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to rain", + "persian": "باران آمدن", + "finglish": "bârân âmadan" + }, + { + "id": "common_verbs_to_read", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to read", + "persian": "خواندن", + "finglish": "khândan" + }, + { + "id": "common_verbs_to_receive", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to receive", + "persian": "دریافت کردن", + "finglish": "daryâft kardan" + }, + { + "id": "common_verbs_to_remember", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to remember", + "persian": "به یاد آوردن", + "finglish": "be yâd âvardan" + }, + { + "id": "common_verbs_to_repair", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to repair", + "persian": "تعمیر کردن", + "finglish": "ta'mir kardan" + }, + { + "id": "common_verbs_to_repeat", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to repeat", + "persian": "تکرار کردن", + "finglish": "tekrâr kardan" + }, + { + "id": "common_verbs_to_rest", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to rest", + "persian": "استراحت کردن", + "finglish": "esterâhat kardan" + }, + { + "id": "common_verbs_to_return", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to return", + "persian": "برگشتن", + "finglish": "bargashtan" + }, + { + "id": "common_verbs_to_run", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to run", + "persian": "دویدن", + "finglish": "davidan" + }, + { + "id": "common_verbs_to_save", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to save", + "persian": "نجات دادن", + "finglish": "nejât dâdan" + }, + { + "id": "common_verbs_to_say", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to say", + "persian": "گفتن", + "finglish": "goftan" + }, + { + "id": "common_verbs_to_see", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to see", + "persian": "دیدن", + "finglish": "didan" + }, + { + "id": "common_verbs_to_sell", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to sell", + "persian": "فروختن", + "finglish": "foroukhtan" + }, + { + "id": "common_verbs_to_send", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to send", + "persian": "فرستادن", + "finglish": "ferestâdan" + }, + { + "id": "common_verbs_to_show", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to show", + "persian": "نشان دادن", + "finglish": "neshân dâdan" + }, + { + "id": "common_verbs_to_sing", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to sing", + "persian": "آواز خواندن", + "finglish": "âvâz khândan" + }, + { + "id": "common_verbs_to_sit", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to sit", + "persian": "نشستن", + "finglish": "neshastan" + }, + { + "id": "common_verbs_to_sleep", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to sleep", + "persian": "خوابیدن", + "finglish": "khâbidan" + }, + { + "id": "common_verbs_to_smell", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to smell", + "persian": "بو کردن", + "finglish": "bu kardan" + }, + { + "id": "common_verbs_to_speak", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to speak", + "persian": "صحبت کردن", + "finglish": "sohbat kardan" + }, + { + "id": "common_verbs_to_spend", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to spend", + "persian": "خرج کردن", + "finglish": "kharj kardan" + }, + { + "id": "common_verbs_to_stand", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to stand", + "persian": "ایستادن", + "finglish": "istâdan" + }, + { + "id": "common_verbs_to_start", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to start", + "persian": "شروع کردن", + "finglish": "shoru' kardan" + }, + { + "id": "common_verbs_to_stay", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to stay", + "persian": "ماندن", + "finglish": "mândan" + }, + { + "id": "common_verbs_to_stop", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to stop", + "persian": "ایستادن", + "finglish": "istâdan" + }, + { + "id": "common_verbs_to_study", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to study", + "persian": "درس خواندن", + "finglish": "dars khândan" + }, + { + "id": "common_verbs_to_succeed", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to succeed", + "persian": "موفق شدن", + "finglish": "movaffagh shodan" + }, + { + "id": "common_verbs_to_swim", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to swim", + "persian": "شنا کردن", + "finglish": "shenâ kardan" + }, + { + "id": "common_verbs_to_take", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to take", + "persian": "گرفتن", + "finglish": "gereftan" + }, + { + "id": "common_verbs_to_talk", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to talk", + "persian": "حرف زدن", + "finglish": "harf zadan" + }, + { + "id": "common_verbs_to_teach", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to teach", + "persian": "درس دادن", + "finglish": "dars dâdan" + }, + { + "id": "common_verbs_to_tell", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to tell", + "persian": "گفتن", + "finglish": "goftan" + }, + { + "id": "common_verbs_to_thank", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to thank", + "persian": "تشکر کردن", + "finglish": "tashakkor kardan" + }, + { + "id": "common_verbs_to_think", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to think", + "persian": "فکر کردن", + "finglish": "fekr kardan" + }, + { + "id": "common_verbs_to_throw", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to throw", + "persian": "پرت کردن", + "finglish": "part kardan" + }, + { + "id": "common_verbs_to_touch", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to touch", + "persian": "لمس کردن", + "finglish": "lams kardan" + }, + { + "id": "common_verbs_to_travel", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to travel", + "persian": "سفر کردن", + "finglish": "safar kardan" + }, + { + "id": "common_verbs_to_try", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to try", + "persian": "سعی کردن", + "finglish": "sa'y kardan" + }, + { + "id": "common_verbs_to_turn", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to turn", + "persian": "چرخیدن", + "finglish": "charkhidan" + }, + { + "id": "common_verbs_to_understand", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to understand", + "persian": "فهمیدن", + "finglish": "fahmidan" + }, + { + "id": "common_verbs_to_use", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to use", + "persian": "استفاده کردن", + "finglish": "estefâde kardan" + }, + { + "id": "common_verbs_to_visit", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to visit", + "persian": "دیدن کردن", + "finglish": "didan kardan" + }, + { + "id": "common_verbs_to_wait", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to wait", + "persian": "صبر کردن", + "finglish": "sabr kardan" + }, + { + "id": "common_verbs_to_wake", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to wake", + "persian": "بیدار شدن", + "finglish": "bidâr shodan" + }, + { + "id": "common_verbs_to_walk", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to walk", + "persian": "راه رفتن", + "finglish": "râh raftan" + }, + { + "id": "common_verbs_to_want", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to want", + "persian": "خواستن", + "finglish": "khâstan" + }, + { + "id": "common_verbs_to_wash", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to wash", + "persian": "شستن", + "finglish": "shostan" + }, + { + "id": "common_verbs_to_watch", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to watch", + "persian": "تماشا کردن", + "finglish": "tamâshâ kardan" + }, + { + "id": "common_verbs_to_wear", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to wear", + "persian": "پوشیدن", + "finglish": "pushidan" + }, + { + "id": "common_verbs_to_win", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to win", + "persian": "برنده شدن", + "finglish": "barande shodan" + }, + { + "id": "common_verbs_to_work", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to work", + "persian": "کار کردن", + "finglish": "kâr kardan" + }, + { + "id": "common_verbs_to_worry", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to worry", + "persian": "نگران بودن", + "finglish": "negarân budan" + }, + { + "id": "common_verbs_to_write", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to write", + "persian": "نوشتن", + "finglish": "neveshtan" + }, + { + "id": "common_adjectives_angry", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "angry", + "persian": "عصبانی", + "finglish": "asabâni" + }, + { + "id": "common_adjectives_bad", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "bad", + "persian": "بد", + "finglish": "bad" + }, + { + "id": "common_adjectives_beautiful", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "beautiful", + "persian": "زیبا", + "finglish": "zibâ" + }, + { + "id": "common_adjectives_big", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "big", + "persian": "بزرگ", + "finglish": "bozorg" + }, + { + "id": "common_adjectives_boring", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "boring", + "persian": "خسته‌کننده", + "finglish": "khaste-konande" + }, + { + "id": "common_adjectives_brave", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "brave", + "persian": "شجاع", + "finglish": "shojâ'" + }, + { + "id": "common_adjectives_busy", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "busy", + "persian": "مشغول", + "finglish": "mashghul" + }, + { + "id": "common_adjectives_calm", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "calm", + "persian": "آرام", + "finglish": "ârâm" + }, + { + "id": "common_adjectives_cheap", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "cheap", + "persian": "ارزان", + "finglish": "arzân" + }, + { + "id": "common_adjectives_clean", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "clean", + "persian": "تمیز", + "finglish": "tamiz" + }, + { + "id": "common_adjectives_clever", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "clever", + "persian": "باهوش", + "finglish": "bâhush" + }, + { + "id": "common_adjectives_close", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "close", + "persian": "نزدیک", + "finglish": "nazdik" + }, + { + "id": "common_adjectives_cold", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "cold", + "persian": "سرد", + "finglish": "sard" + }, + { + "id": "common_adjectives_comfortable", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "comfortable", + "persian": "راحت", + "finglish": "râhat" + }, + { + "id": "common_adjectives_correct", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "correct", + "persian": "درست", + "finglish": "dorost" + }, + { + "id": "common_adjectives_dangerous", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "dangerous", + "persian": "خطرناک", + "finglish": "khatarnâk" + }, + { + "id": "common_adjectives_dark", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "dark", + "persian": "تاریک", + "finglish": "târik" + }, + { + "id": "common_adjectives_dear", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "dear", + "persian": "عزیز", + "finglish": "aziz" + }, + { + "id": "common_adjectives_deep", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "deep", + "persian": "عمیق", + "finglish": "amigh" + }, + { + "id": "common_adjectives_delicious", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "delicious", + "persian": "خوشمزه", + "finglish": "khoshmaze" + }, + { + "id": "common_adjectives_difficult", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "difficult", + "persian": "سخت", + "finglish": "sakht" + }, + { + "id": "common_adjectives_dirty", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "dirty", + "persian": "کثیف", + "finglish": "kasif" + }, + { + "id": "common_adjectives_dry", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "dry", + "persian": "خشک", + "finglish": "khoshk" + }, + { + "id": "common_adjectives_easy", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "easy", + "persian": "آسان", + "finglish": "âsân" + }, + { + "id": "common_adjectives_empty", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "empty", + "persian": "خالی", + "finglish": "khâli" + }, + { + "id": "common_adjectives_excellent", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "excellent", + "persian": "عالی", + "finglish": "âli" + }, + { + "id": "common_adjectives_exciting", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "exciting", + "persian": "هیجان‌انگیز", + "finglish": "hayajân-angiz" + }, + { + "id": "common_adjectives_expensive", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "expensive", + "persian": "گران", + "finglish": "gerân" + }, + { + "id": "common_adjectives_famous", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "famous", + "persian": "مشهور", + "finglish": "mashhur" + }, + { + "id": "common_adjectives_far", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "far", + "persian": "دور", + "finglish": "dur" + }, + { + "id": "common_adjectives_fast", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "fast", + "persian": "سریع", + "finglish": "sari'" + }, + { + "id": "common_adjectives_fat", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "fat", + "persian": "چاق", + "finglish": "châgh" + }, + { + "id": "common_adjectives_favourite", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "favourite", + "persian": "مورد علاقه", + "finglish": "mored-e alâghe" + }, + { + "id": "common_adjectives_foreign", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "foreign", + "persian": "خارجی", + "finglish": "khâreji" + }, + { + "id": "common_adjectives_free", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "free", + "persian": "آزاد", + "finglish": "âzâd" + }, + { + "id": "common_adjectives_friendly", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "friendly", + "persian": "مهربان", + "finglish": "mehrabân" + }, + { + "id": "common_adjectives_full", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "full", + "persian": "پر", + "finglish": "por" + }, + { + "id": "common_adjectives_funny", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "funny", + "persian": "خنده‌دار", + "finglish": "khande-dâr" + }, + { + "id": "common_adjectives_good", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "good", + "persian": "خوب", + "finglish": "khub" + }, + { + "id": "common_adjectives_great", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "great", + "persian": "عالی", + "finglish": "âli" + }, + { + "id": "common_adjectives_happy", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "happy", + "persian": "خوشحال", + "finglish": "khoshhâl" + }, + { + "id": "common_adjectives_hard", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "hard", + "persian": "سخت", + "finglish": "sakht" + }, + { + "id": "common_adjectives_healthy", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "healthy", + "persian": "سالم", + "finglish": "sâlem" + }, + { + "id": "common_adjectives_heavy", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "heavy", + "persian": "سنگین", + "finglish": "sangin" + }, + { + "id": "common_adjectives_high", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "high", + "persian": "بلند", + "finglish": "boland" + }, + { + "id": "common_adjectives_honest", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "honest", + "persian": "صادق", + "finglish": "sâdegh" + }, + { + "id": "common_adjectives_horrible", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "horrible", + "persian": "وحشتناک", + "finglish": "vahshatnâk" + }, + { + "id": "common_adjectives_hot", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "hot", + "persian": "داغ", + "finglish": "dâgh" + }, + { + "id": "common_adjectives_huge", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "huge", + "persian": "عظیم", + "finglish": "azim" + }, + { + "id": "common_adjectives_hungry", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "hungry", + "persian": "گرسنه", + "finglish": "gorosne" + }, + { + "id": "common_adjectives_ill", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "ill", + "persian": "مریض", + "finglish": "mariz" + }, + { + "id": "common_adjectives_important", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "important", + "persian": "مهم", + "finglish": "mohem" + }, + { + "id": "common_adjectives_impossible", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "impossible", + "persian": "غیرممکن", + "finglish": "gheyr-e momken" + }, + { + "id": "common_adjectives_interesting", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "interesting", + "persian": "جالب", + "finglish": "jâleb" + }, + { + "id": "common_adjectives_kind", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "kind", + "persian": "مهربان", + "finglish": "mehrabân" + }, + { + "id": "common_adjectives_large", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "large", + "persian": "بزرگ", + "finglish": "bozorg" + }, + { + "id": "common_adjectives_last", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "last", + "persian": "آخرین", + "finglish": "âkharin" + }, + { + "id": "common_adjectives_late", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "late", + "persian": "دیر", + "finglish": "dir" + }, + { + "id": "common_adjectives_lazy", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "lazy", + "persian": "تنبل", + "finglish": "tanbal" + }, + { + "id": "common_adjectives_light", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "light", + "persian": "سبک", + "finglish": "sabok" + }, + { + "id": "common_adjectives_long", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "long", + "persian": "بلند", + "finglish": "boland" + }, + { + "id": "common_adjectives_loud", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "loud", + "persian": "بلند", + "finglish": "boland" + }, + { + "id": "common_adjectives_low", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "low", + "persian": "پایین", + "finglish": "pâyin" + }, + { + "id": "common_adjectives_lucky", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "lucky", + "persian": "خوش‌شانس", + "finglish": "khosh-shâns" + }, + { + "id": "common_adjectives_modern", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "modern", + "persian": "مدرن", + "finglish": "modern" + }, + { + "id": "common_adjectives_narrow", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "narrow", + "persian": "باریک", + "finglish": "bârik" + }, + { + "id": "common_adjectives_natural", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "natural", + "persian": "طبیعی", + "finglish": "tabi'i" + }, + { + "id": "common_adjectives_near", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "near", + "persian": "نزدیک", + "finglish": "nazdik" + }, + { + "id": "common_adjectives_necessary", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "necessary", + "persian": "لازم", + "finglish": "lâzem" + }, + { + "id": "common_adjectives_new", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "new", + "persian": "نو", + "finglish": "now" + }, + { + "id": "common_adjectives_nice", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "nice", + "persian": "خوب", + "finglish": "khub" + }, + { + "id": "common_adjectives_noisy", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "noisy", + "persian": "پر سر و صدا", + "finglish": "por sar o sedâ" + }, + { + "id": "common_adjectives_normal", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "normal", + "persian": "عادی", + "finglish": "âdi" + }, + { + "id": "common_adjectives_old", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "old", + "persian": "پیر", + "finglish": "pir" + }, + { + "id": "common_adjectives_open", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "open", + "persian": "باز", + "finglish": "bâz" + }, + { + "id": "common_adjectives_painful", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "painful", + "persian": "دردناک", + "finglish": "dardnâk" + }, + { + "id": "common_adjectives_perfect", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "perfect", + "persian": "عالی", + "finglish": "âli" + }, + { + "id": "common_adjectives_pleasant", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "pleasant", + "persian": "خوشایند", + "finglish": "khoshâyand" + }, + { + "id": "common_adjectives_polite", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "polite", + "persian": "مودب", + "finglish": "mo'addab" + }, + { + "id": "common_adjectives_poor", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "poor", + "persian": "فقیر", + "finglish": "faghir" + }, + { + "id": "common_adjectives_popular", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "popular", + "persian": "محبوب", + "finglish": "mahbub" + }, + { + "id": "common_adjectives_possible", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "possible", + "persian": "ممکن", + "finglish": "momken" + }, + { + "id": "common_adjectives_pretty", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "pretty", + "persian": "قشنگ", + "finglish": "ghashang" + }, + { + "id": "common_adjectives_private", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "private", + "persian": "خصوصی", + "finglish": "khosusi" + }, + { + "id": "common_adjectives_proud", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "proud", + "persian": "مفتخر", + "finglish": "moftakher" + }, + { + "id": "common_adjectives_quiet", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "quiet", + "persian": "ساکت", + "finglish": "sâket" + }, + { + "id": "common_adjectives_quick", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "quick", + "persian": "سریع", + "finglish": "sari'" + }, + { + "id": "common_adjectives_ready", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "ready", + "persian": "آماده", + "finglish": "âmâde" + }, + { + "id": "common_adjectives_real", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "real", + "persian": "واقعی", + "finglish": "vâghe'i" + }, + { + "id": "common_adjectives_rich", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "rich", + "persian": "پولدار", + "finglish": "puldâr" + }, + { + "id": "common_adjectives_right", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "right", + "persian": "درست", + "finglish": "dorost" + }, + { + "id": "common_adjectives_rude", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "rude", + "persian": "بی‌ادب", + "finglish": "bi-adab" + }, + { + "id": "common_adjectives_sad", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "sad", + "persian": "غمگین", + "finglish": "ghamgin" + }, + { + "id": "common_adjectives_safe", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "safe", + "persian": "امن", + "finglish": "amn" + }, + { + "id": "common_adjectives_serious", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "serious", + "persian": "جدی", + "finglish": "jeddi" + }, + { + "id": "common_adjectives_short", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "short", + "persian": "کوتاه", + "finglish": "kutâh" + }, + { + "id": "common_adjectives_simple", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "simple", + "persian": "ساده", + "finglish": "sâde" + }, + { + "id": "common_adjectives_slow", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "slow", + "persian": "آهسته", + "finglish": "âheste" + }, + { + "id": "common_adjectives_small", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "small", + "persian": "کوچک", + "finglish": "kuchak" + }, + { + "id": "common_adjectives_smart", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "smart", + "persian": "باهوش", + "finglish": "bâhush" + }, + { + "id": "common_adjectives_soft", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "soft", + "persian": "نرم", + "finglish": "narm" + }, + { + "id": "common_adjectives_special", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "special", + "persian": "خاص", + "finglish": "khâss" + }, + { + "id": "common_adjectives_strange", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "strange", + "persian": "عجیب", + "finglish": "ajib" + }, + { + "id": "common_adjectives_strict", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "strict", + "persian": "سختگیر", + "finglish": "sakhtgir" + }, + { + "id": "common_adjectives_strong", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "strong", + "persian": "قوی", + "finglish": "ghavi" + }, + { + "id": "common_adjectives_stupid", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "stupid", + "persian": "احمق", + "finglish": "ahmagh" + }, + { + "id": "common_adjectives_successful", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "successful", + "persian": "موفق", + "finglish": "movaffagh" + }, + { + "id": "common_adjectives_sure", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "sure", + "persian": "مطمئن", + "finglish": "motma'en" + }, + { + "id": "common_adjectives_surprised", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "surprised", + "persian": "متعجب", + "finglish": "mota'ajjeb" + }, + { + "id": "common_adjectives_sweet", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "sweet", + "persian": "شیرین", + "finglish": "shirin" + }, + { + "id": "common_adjectives_tall", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "tall", + "persian": "بلند قد", + "finglish": "boland-ghad" + }, + { + "id": "common_adjectives_terrible", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "terrible", + "persian": "وحشتناک", + "finglish": "vahshatnâk" + }, + { + "id": "common_adjectives_thin", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "thin", + "persian": "لاغر", + "finglish": "lâghar" + }, + { + "id": "common_adjectives_thirsty", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "thirsty", + "persian": "تشنه", + "finglish": "teshne" + }, + { + "id": "common_adjectives_tired", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "tired", + "persian": "خسته", + "finglish": "khaste" + }, + { + "id": "common_adjectives_traditional", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "traditional", + "persian": "سنتی", + "finglish": "sonnati" + }, + { + "id": "common_adjectives_true", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "true", + "persian": "درست", + "finglish": "dorost" + }, + { + "id": "common_adjectives_ugly", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "ugly", + "persian": "زشت", + "finglish": "zesht" + }, + { + "id": "common_adjectives_unfair", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "unfair", + "persian": "ناعادلانه", + "finglish": "nâ-âdelâne" + }, + { + "id": "common_adjectives_unhappy", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "unhappy", + "persian": "ناراحت", + "finglish": "nârâhat" + }, + { + "id": "common_adjectives_useful", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "useful", + "persian": "مفید", + "finglish": "mofid" + }, + { + "id": "common_adjectives_usual", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "usual", + "persian": "معمولی", + "finglish": "ma'muli" + }, + { + "id": "common_adjectives_warm", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "warm", + "persian": "گرم", + "finglish": "garm" + }, + { + "id": "common_adjectives_weak", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "weak", + "persian": "ضعیف", + "finglish": "za'if" + }, + { + "id": "common_adjectives_well", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "well", + "persian": "خوب", + "finglish": "khub" + }, + { + "id": "common_adjectives_whole", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "whole", + "persian": "کامل", + "finglish": "kâmel" + }, + { + "id": "common_adjectives_wide", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "wide", + "persian": "پهن", + "finglish": "pahn" + }, + { + "id": "common_adjectives_wild", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "wild", + "persian": "وحشی", + "finglish": "vahshi" + }, + { + "id": "common_adjectives_wonderful", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "wonderful", + "persian": "فوق‌العاده", + "finglish": "fogh-ol-âde" + }, + { + "id": "common_adjectives_worried", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "worried", + "persian": "نگران", + "finglish": "negarân" + }, + { + "id": "common_adjectives_wrong", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "wrong", + "persian": "اشتباه", + "finglish": "eshtebâh" + }, + { + "id": "common_adjectives_young", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "young", + "persian": "جوان", + "finglish": "javân" + }, + { + "id": "common_adverbs_a_lot", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "a lot", + "persian": "زیاد", + "finglish": "ziyâd" + }, + { + "id": "common_adverbs_again", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "again", + "persian": "دوباره", + "finglish": "dobâre" + }, + { + "id": "common_adverbs_almost", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "almost", + "persian": "تقریبا", + "finglish": "taghribân" + }, + { + "id": "common_adverbs_already", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "already", + "persian": "قبلا", + "finglish": "ghablan" + }, + { + "id": "common_adverbs_also", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "also", + "persian": "همچنین", + "finglish": "hamchenin" + }, + { + "id": "common_adverbs_always", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "always", + "persian": "همیشه", + "finglish": "hamishe" + }, + { + "id": "common_adverbs_badly", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "badly", + "persian": "بد", + "finglish": "bad" + }, + { + "id": "common_adverbs_carefully", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "carefully", + "persian": "با دقت", + "finglish": "bâ deghat" + }, + { + "id": "common_adverbs_certainly", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "certainly", + "persian": "حتما", + "finglish": "hatman" + }, + { + "id": "common_adverbs_clearly", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "clearly", + "persian": "واضح", + "finglish": "vâzeh" + }, + { + "id": "common_adverbs_completely", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "completely", + "persian": "کاملا", + "finglish": "kâmelan" + }, + { + "id": "common_adverbs_early", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "early", + "persian": "زود", + "finglish": "zud" + }, + { + "id": "common_adverbs_enough", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "enough", + "persian": "کافی", + "finglish": "kâfi" + }, + { + "id": "common_adverbs_especially", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "especially", + "persian": "مخصوصا", + "finglish": "makhsusan" + }, + { + "id": "common_adverbs_even", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "even", + "persian": "حتی", + "finglish": "hattâ" + }, + { + "id": "common_adverbs_exactly", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "exactly", + "persian": "دقیقا", + "finglish": "daghighan" + }, + { + "id": "common_adverbs_finally", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "finally", + "persian": "بالاخره", + "finglish": "belâkhare" + }, + { + "id": "common_adverbs_fortunately", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "fortunately", + "persian": "خوشبختانه", + "finglish": "khoshbakhtâne" + }, + { + "id": "common_adverbs_generally", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "generally", + "persian": "معمولا", + "finglish": "ma'mulan" + }, + { + "id": "common_adverbs_hardly", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "hardly", + "persian": "به سختی", + "finglish": "be sakhti" + }, + { + "id": "common_adverbs_immediately", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "immediately", + "persian": "فورا", + "finglish": "fowran" + }, + { + "id": "common_adverbs_just", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "just", + "persian": "فقط", + "finglish": "faghat" + }, + { + "id": "common_adverbs_late", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "late", + "persian": "دیر", + "finglish": "dir" + }, + { + "id": "common_adverbs_loudly", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "loudly", + "persian": "بلند", + "finglish": "boland" + }, + { + "id": "common_adverbs_maybe", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "maybe", + "persian": "شاید", + "finglish": "shâyad" + }, + { + "id": "common_adverbs_never", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "never", + "persian": "هرگز", + "finglish": "hargez" + }, + { + "id": "common_adverbs_normally", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "normally", + "persian": "معمولا", + "finglish": "ma'mulan" + }, + { + "id": "common_adverbs_often", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "often", + "persian": "اغلب", + "finglish": "aghlab" + }, + { + "id": "common_adverbs_only", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "only", + "persian": "فقط", + "finglish": "faghat" + }, + { + "id": "common_adverbs_perhaps", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "perhaps", + "persian": "شاید", + "finglish": "shâyad" + }, + { + "id": "common_adverbs_please", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "please", + "persian": "لطفا", + "finglish": "lotfan" + }, + { + "id": "common_adverbs_quickly", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "quickly", + "persian": "سریع", + "finglish": "sari'" + }, + { + "id": "common_adverbs_quite", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "quite", + "persian": "نسبتا", + "finglish": "nesbatan" + }, + { + "id": "common_adverbs_rarely", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "rarely", + "persian": "به ندرت", + "finglish": "be nodrat" + }, + { + "id": "common_adverbs_really", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "really", + "persian": "واقعا", + "finglish": "vâghe'an" + }, + { + "id": "common_adverbs_recently", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "recently", + "persian": "اخیرا", + "finglish": "akhiran" + }, + { + "id": "common_adverbs_regularly", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "regularly", + "persian": "مرتب", + "finglish": "morattab" + }, + { + "id": "common_adverbs_slowly", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "slowly", + "persian": "آهسته", + "finglish": "âheste" + }, + { + "id": "common_adverbs_sometimes", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "sometimes", + "persian": "گاهی", + "finglish": "gâhi" + }, + { + "id": "common_adverbs_soon", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "soon", + "persian": "زود", + "finglish": "zud" + }, + { + "id": "common_adverbs_still", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "still", + "persian": "هنوز", + "finglish": "hanuz" + }, + { + "id": "common_adverbs_suddenly", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "suddenly", + "persian": "ناگهان", + "finglish": "nâgahân" + }, + { + "id": "common_adverbs_then", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "then", + "persian": "سپس", + "finglish": "sepas" + }, + { + "id": "common_adverbs_together", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "together", + "persian": "با هم", + "finglish": "bâ ham" + }, + { + "id": "common_adverbs_too", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "too", + "persian": "هم", + "finglish": "ham" + }, + { + "id": "common_adverbs_unfortunately", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "unfortunately", + "persian": "متاسفانه", + "finglish": "mota'assefâne" + }, + { + "id": "common_adverbs_usually", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "usually", + "persian": "معمولا", + "finglish": "ma'mulan" + }, + { + "id": "common_adverbs_very", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "very", + "persian": "خیلی", + "finglish": "kheyli" + }, + { + "id": "common_adverbs_well", + "section": "High-frequency language", + "category": "Common adverbs", + "english": "well", + "persian": "خوب", + "finglish": "khub" + }, + { + "id": "prepositions_about", + "section": "High-frequency language", + "category": "Prepositions", + "english": "about", + "persian": "درباره", + "finglish": "darbâre" + }, + { + "id": "prepositions_above", + "section": "High-frequency language", + "category": "Prepositions", + "english": "above", + "persian": "بالای", + "finglish": "bâlâ-ye" + }, + { + "id": "prepositions_across", + "section": "High-frequency language", + "category": "Prepositions", + "english": "across", + "persian": "آن طرف", + "finglish": "ân taraf" + }, + { + "id": "prepositions_after", + "section": "High-frequency language", + "category": "Prepositions", + "english": "after", + "persian": "بعد از", + "finglish": "ba'd az" + }, + { + "id": "prepositions_against", + "section": "High-frequency language", + "category": "Prepositions", + "english": "against", + "persian": "بر علیه", + "finglish": "bar aleyhe" + }, + { + "id": "prepositions_along", + "section": "High-frequency language", + "category": "Prepositions", + "english": "along", + "persian": "در امتداد", + "finglish": "dar emtedâd" + }, + { + "id": "prepositions_among", + "section": "High-frequency language", + "category": "Prepositions", + "english": "among", + "persian": "در میان", + "finglish": "dar miyân" + }, + { + "id": "prepositions_around", + "section": "High-frequency language", + "category": "Prepositions", + "english": "around", + "persian": "اطراف", + "finglish": "atrâf" + }, + { + "id": "prepositions_at", + "section": "High-frequency language", + "category": "Prepositions", + "english": "at", + "persian": "در", + "finglish": "dar" + }, + { + "id": "prepositions_before", + "section": "High-frequency language", + "category": "Prepositions", + "english": "before", + "persian": "قبل از", + "finglish": "ghabl az" + }, + { + "id": "prepositions_behind", + "section": "High-frequency language", + "category": "Prepositions", + "english": "behind", + "persian": "پشت", + "finglish": "posht" + }, + { + "id": "prepositions_below", + "section": "High-frequency language", + "category": "Prepositions", + "english": "below", + "persian": "زیر", + "finglish": "zir" + }, + { + "id": "prepositions_beside", + "section": "High-frequency language", + "category": "Prepositions", + "english": "beside", + "persian": "کنار", + "finglish": "kenâr" + }, + { + "id": "prepositions_between", + "section": "High-frequency language", + "category": "Prepositions", + "english": "between", + "persian": "بین", + "finglish": "beyn" + }, + { + "id": "prepositions_by", + "section": "High-frequency language", + "category": "Prepositions", + "english": "by", + "persian": "توسط", + "finglish": "tavasot" + }, + { + "id": "prepositions_down", + "section": "High-frequency language", + "category": "Prepositions", + "english": "down", + "persian": "پایین", + "finglish": "pâyin" + }, + { + "id": "prepositions_during", + "section": "High-frequency language", + "category": "Prepositions", + "english": "during", + "persian": "در طول", + "finglish": "dar tul" + }, + { + "id": "prepositions_except", + "section": "High-frequency language", + "category": "Prepositions", + "english": "except", + "persian": "به جز", + "finglish": "be joz" + }, + { + "id": "prepositions_for", + "section": "High-frequency language", + "category": "Prepositions", + "english": "for", + "persian": "برای", + "finglish": "barâye" + }, + { + "id": "prepositions_from", + "section": "High-frequency language", + "category": "Prepositions", + "english": "from", + "persian": "از", + "finglish": "az" + }, + { + "id": "prepositions_in", + "section": "High-frequency language", + "category": "Prepositions", + "english": "in", + "persian": "در", + "finglish": "dar" + }, + { + "id": "prepositions_inside", + "section": "High-frequency language", + "category": "Prepositions", + "english": "inside", + "persian": "داخل", + "finglish": "dâkhel" + }, + { + "id": "prepositions_into", + "section": "High-frequency language", + "category": "Prepositions", + "english": "into", + "persian": "به داخل", + "finglish": "be dâkhel" + }, + { + "id": "prepositions_near", + "section": "High-frequency language", + "category": "Prepositions", + "english": "near", + "persian": "نزدیک", + "finglish": "nazdik" + }, + { + "id": "prepositions_of", + "section": "High-frequency language", + "category": "Prepositions", + "english": "of", + "persian": "از", + "finglish": "az" + }, + { + "id": "prepositions_on", + "section": "High-frequency language", + "category": "Prepositions", + "english": "on", + "persian": "روی", + "finglish": "ru-ye" + }, + { + "id": "prepositions_opposite", + "section": "High-frequency language", + "category": "Prepositions", + "english": "opposite", + "persian": "روبروی", + "finglish": "ruberu-ye" + }, + { + "id": "prepositions_out", + "section": "High-frequency language", + "category": "Prepositions", + "english": "out", + "persian": "بیرون", + "finglish": "birun" + }, + { + "id": "prepositions_outside", + "section": "High-frequency language", + "category": "Prepositions", + "english": "outside", + "persian": "بیرون از", + "finglish": "birun az" + }, + { + "id": "prepositions_over", + "section": "High-frequency language", + "category": "Prepositions", + "english": "over", + "persian": "بالای", + "finglish": "bâlâ-ye" + }, + { + "id": "prepositions_through", + "section": "High-frequency language", + "category": "Prepositions", + "english": "through", + "persian": "از میان", + "finglish": "az miyân" + }, + { + "id": "prepositions_to", + "section": "High-frequency language", + "category": "Prepositions", + "english": "to", + "persian": "به", + "finglish": "be" + }, + { + "id": "prepositions_towards", + "section": "High-frequency language", + "category": "Prepositions", + "english": "towards", + "persian": "به سوی", + "finglish": "be su-ye" + }, + { + "id": "prepositions_under", + "section": "High-frequency language", + "category": "Prepositions", + "english": "under", + "persian": "زیر", + "finglish": "zir" + }, + { + "id": "prepositions_until", + "section": "High-frequency language", + "category": "Prepositions", + "english": "until", + "persian": "تا", + "finglish": "tâ" + }, + { + "id": "prepositions_up", + "section": "High-frequency language", + "category": "Prepositions", + "english": "up", + "persian": "بالا", + "finglish": "bâlâ" + }, + { + "id": "prepositions_with", + "section": "High-frequency language", + "category": "Prepositions", + "english": "with", + "persian": "با", + "finglish": "bâ" + }, + { + "id": "prepositions_without", + "section": "High-frequency language", + "category": "Prepositions", + "english": "without", + "persian": "بدون", + "finglish": "bedun" + }, + { + "id": "colours_black", + "section": "High-frequency language", + "category": "Colours", + "english": "black", + "persian": "سیاه", + "finglish": "siyâh" + }, + { + "id": "colours_blue", + "section": "High-frequency language", + "category": "Colours", + "english": "blue", + "persian": "آبی", + "finglish": "âbi" + }, + { + "id": "colours_brown", + "section": "High-frequency language", + "category": "Colours", + "english": "brown", + "persian": "قهوه‌ای", + "finglish": "ghahve-i" + }, + { + "id": "colours_gold", + "section": "High-frequency language", + "category": "Colours", + "english": "gold", + "persian": "طلایی", + "finglish": "talâyi" + }, + { + "id": "colours_green", + "section": "High-frequency language", + "category": "Colours", + "english": "green", + "persian": "سبز", + "finglish": "sabz" + }, + { + "id": "colours_grey", + "section": "High-frequency language", + "category": "Colours", + "english": "grey", + "persian": "خاکستری", + "finglish": "khâkestari" + }, + { + "id": "colours_orange", + "section": "High-frequency language", + "category": "Colours", + "english": "orange", + "persian": "نارنجی", + "finglish": "nârenji" + }, + { + "id": "colours_pink", + "section": "High-frequency language", + "category": "Colours", + "english": "pink", + "persian": "صورتی", + "finglish": "surati" + }, + { + "id": "colours_purple", + "section": "High-frequency language", + "category": "Colours", + "english": "purple", + "persian": "بنفش", + "finglish": "banafsh" + }, + { + "id": "colours_red", + "section": "High-frequency language", + "category": "Colours", + "english": "red", + "persian": "قرمز", + "finglish": "ghermez" + }, + { + "id": "colours_silver", + "section": "High-frequency language", + "category": "Colours", + "english": "silver", + "persian": "نقره‌ای", + "finglish": "noghre-i" + }, + { + "id": "colours_white", + "section": "High-frequency language", + "category": "Colours", + "english": "white", + "persian": "سفید", + "finglish": "sefid" + }, + { + "id": "colours_yellow", + "section": "High-frequency language", + "category": "Colours", + "english": "yellow", + "persian": "زرد", + "finglish": "zard" + }, + { + "id": "numbers_zero", + "section": "High-frequency language", + "category": "Numbers", + "english": "zero", + "persian": "صفر", + "finglish": "sefr" + }, + { + "id": "numbers_one", + "section": "High-frequency language", + "category": "Numbers", + "english": "one", + "persian": "یک", + "finglish": "yek" + }, + { + "id": "numbers_two", + "section": "High-frequency language", + "category": "Numbers", + "english": "two", + "persian": "دو", + "finglish": "do" + }, + { + "id": "numbers_three", + "section": "High-frequency language", + "category": "Numbers", + "english": "three", + "persian": "سه", + "finglish": "se" + }, + { + "id": "numbers_four", + "section": "High-frequency language", + "category": "Numbers", + "english": "four", + "persian": "چهار", + "finglish": "chahâr" + }, + { + "id": "numbers_five", + "section": "High-frequency language", + "category": "Numbers", + "english": "five", + "persian": "پنج", + "finglish": "panj" + }, + { + "id": "numbers_six", + "section": "High-frequency language", + "category": "Numbers", + "english": "six", + "persian": "شش", + "finglish": "shesh" + }, + { + "id": "numbers_seven", + "section": "High-frequency language", + "category": "Numbers", + "english": "seven", + "persian": "هفت", + "finglish": "haft" + }, + { + "id": "numbers_eight", + "section": "High-frequency language", + "category": "Numbers", + "english": "eight", + "persian": "هشت", + "finglish": "hasht" + }, + { + "id": "numbers_nine", + "section": "High-frequency language", + "category": "Numbers", + "english": "nine", + "persian": "نه", + "finglish": "noh" + }, + { + "id": "numbers_ten", + "section": "High-frequency language", + "category": "Numbers", + "english": "ten", + "persian": "ده", + "finglish": "dah" + }, + { + "id": "numbers_eleven", + "section": "High-frequency language", + "category": "Numbers", + "english": "eleven", + "persian": "یازده", + "finglish": "yâzdah" + }, + { + "id": "numbers_twelve", + "section": "High-frequency language", + "category": "Numbers", + "english": "twelve", + "persian": "دوازده", + "finglish": "davâzdah" + }, + { + "id": "numbers_thirteen", + "section": "High-frequency language", + "category": "Numbers", + "english": "thirteen", + "persian": "سیزده", + "finglish": "sizdah" + }, + { + "id": "numbers_fourteen", + "section": "High-frequency language", + "category": "Numbers", + "english": "fourteen", + "persian": "چهارده", + "finglish": "chahârdah" + }, + { + "id": "numbers_fifteen", + "section": "High-frequency language", + "category": "Numbers", + "english": "fifteen", + "persian": "پانزده", + "finglish": "pânzdah" + }, + { + "id": "numbers_sixteen", + "section": "High-frequency language", + "category": "Numbers", + "english": "sixteen", + "persian": "شانزده", + "finglish": "shânzdah" + }, + { + "id": "numbers_seventeen", + "section": "High-frequency language", + "category": "Numbers", + "english": "seventeen", + "persian": "هفده", + "finglish": "hefdah" + }, + { + "id": "numbers_eighteen", + "section": "High-frequency language", + "category": "Numbers", + "english": "eighteen", + "persian": "هجده", + "finglish": "hejdah" + }, + { + "id": "numbers_nineteen", + "section": "High-frequency language", + "category": "Numbers", + "english": "nineteen", + "persian": "نوزده", + "finglish": "nuzdah" + }, + { + "id": "numbers_twenty", + "section": "High-frequency language", + "category": "Numbers", + "english": "twenty", + "persian": "بیست", + "finglish": "bist" + }, + { + "id": "numbers_thirty", + "section": "High-frequency language", + "category": "Numbers", + "english": "thirty", + "persian": "سی", + "finglish": "si" + }, + { + "id": "numbers_forty", + "section": "High-frequency language", + "category": "Numbers", + "english": "forty", + "persian": "چهل", + "finglish": "chehel" + }, + { + "id": "numbers_fifty", + "section": "High-frequency language", + "category": "Numbers", + "english": "fifty", + "persian": "پنجاه", + "finglish": "panjâh" + }, + { + "id": "numbers_sixty", + "section": "High-frequency language", + "category": "Numbers", + "english": "sixty", + "persian": "شصت", + "finglish": "shast" + }, + { + "id": "numbers_seventy", + "section": "High-frequency language", + "category": "Numbers", + "english": "seventy", + "persian": "هفتاد", + "finglish": "haftâd" + }, + { + "id": "numbers_eighty", + "section": "High-frequency language", + "category": "Numbers", + "english": "eighty", + "persian": "هشتاد", + "finglish": "hashtâd" + }, + { + "id": "numbers_ninety", + "section": "High-frequency language", + "category": "Numbers", + "english": "ninety", + "persian": "نود", + "finglish": "navad" + }, + { + "id": "numbers_hundred", + "section": "High-frequency language", + "category": "Numbers", + "english": "hundred", + "persian": "صد", + "finglish": "sad" + }, + { + "id": "numbers_thousand", + "section": "High-frequency language", + "category": "Numbers", + "english": "thousand", + "persian": "هزار", + "finglish": "hezâr" + }, + { + "id": "numbers_million", + "section": "High-frequency language", + "category": "Numbers", + "english": "million", + "persian": "میلیون", + "finglish": "milyun" + }, + { + "id": "numbers_first", + "section": "High-frequency language", + "category": "Numbers", + "english": "first", + "persian": "اول", + "finglish": "avval" + }, + { + "id": "numbers_second", + "section": "High-frequency language", + "category": "Numbers", + "english": "second", + "persian": "دوم", + "finglish": "dovvom" + }, + { + "id": "numbers_third", + "section": "High-frequency language", + "category": "Numbers", + "english": "third", + "persian": "سوم", + "finglish": "sevvom" + }, + { + "id": "numbers_fourth", + "section": "High-frequency language", + "category": "Numbers", + "english": "fourth", + "persian": "چهارم", + "finglish": "chahârom" + }, + { + "id": "numbers_fifth", + "section": "High-frequency language", + "category": "Numbers", + "english": "fifth", + "persian": "پنجم", + "finglish": "panjom" + }, + { + "id": "numbers_last", + "section": "High-frequency language", + "category": "Numbers", + "english": "last", + "persian": "آخر", + "finglish": "âkhar" + }, + { + "id": "quantities_and_measures_all", + "section": "High-frequency language", + "category": "Quantities and measures", + "english": "all", + "persian": "همه", + "finglish": "hame" + }, + { + "id": "quantities_and_measures_another", + "section": "High-frequency language", + "category": "Quantities and measures", + "english": "another", + "persian": "یکی دیگر", + "finglish": "yeki digar" + }, + { + "id": "quantities_and_measures_both", + "section": "High-frequency language", + "category": "Quantities and measures", + "english": "both", + "persian": "هر دو", + "finglish": "har do" + }, + { + "id": "quantities_and_measures_each", + "section": "High-frequency language", + "category": "Quantities and measures", + "english": "each", + "persian": "هر", + "finglish": "har" + }, + { + "id": "quantities_and_measures_enough", + "section": "High-frequency language", + "category": "Quantities and measures", + "english": "enough", + "persian": "کافی", + "finglish": "kâfi" + }, + { + "id": "quantities_and_measures_every", + "section": "High-frequency language", + "category": "Quantities and measures", + "english": "every", + "persian": "هر", + "finglish": "har" + }, + { + "id": "quantities_and_measures_few", + "section": "High-frequency language", + "category": "Quantities and measures", + "english": "few", + "persian": "کم", + "finglish": "kam" + }, + { + "id": "quantities_and_measures_half", + "section": "High-frequency language", + "category": "Quantities and measures", + "english": "half", + "persian": "نصف", + "finglish": "nesf" + }, + { + "id": "quantities_and_measures_less", + "section": "High-frequency language", + "category": "Quantities and measures", + "english": "less", + "persian": "کمتر", + "finglish": "kamtar" + }, + { + "id": "quantities_and_measures_little", + "section": "High-frequency language", + "category": "Quantities and measures", + "english": "little", + "persian": "کمی", + "finglish": "kami" + }, + { + "id": "quantities_and_measures_many", + "section": "High-frequency language", + "category": "Quantities and measures", + "english": "many", + "persian": "زیاد", + "finglish": "ziyâd" + }, + { + "id": "quantities_and_measures_more", + "section": "High-frequency language", + "category": "Quantities and measures", + "english": "more", + "persian": "بیشتر", + "finglish": "bishtar" + }, + { + "id": "quantities_and_measures_most", + "section": "High-frequency language", + "category": "Quantities and measures", + "english": "most", + "persian": "بیشترین", + "finglish": "bishtarin" + }, + { + "id": "quantities_and_measures_much", + "section": "High-frequency language", + "category": "Quantities and measures", + "english": "much", + "persian": "زیاد", + "finglish": "ziyâd" + }, + { + "id": "quantities_and_measures_none", + "section": "High-frequency language", + "category": "Quantities and measures", + "english": "none", + "persian": "هیچ‌کدام", + "finglish": "hich-kodâm" + }, + { + "id": "quantities_and_measures_other", + "section": "High-frequency language", + "category": "Quantities and measures", + "english": "other", + "persian": "دیگر", + "finglish": "digar" + }, + { + "id": "quantities_and_measures_several", + "section": "High-frequency language", + "category": "Quantities and measures", + "english": "several", + "persian": "چندین", + "finglish": "chandin" + }, + { + "id": "quantities_and_measures_some", + "section": "High-frequency language", + "category": "Quantities and measures", + "english": "some", + "persian": "بعضی", + "finglish": "ba'zi" + }, + { + "id": "quantities_and_measures_pair", + "section": "High-frequency language", + "category": "Quantities and measures", + "english": "pair", + "persian": "جفت", + "finglish": "joft" + }, + { + "id": "quantities_and_measures_piece", + "section": "High-frequency language", + "category": "Quantities and measures", + "english": "piece", + "persian": "تکه", + "finglish": "tekke" + }, + { + "id": "quantities_and_measures_part", + "section": "High-frequency language", + "category": "Quantities and measures", + "english": "part", + "persian": "بخش", + "finglish": "bakhsh" + }, + { + "id": "quantities_and_measures_kilo", + "section": "High-frequency language", + "category": "Quantities and measures", + "english": "kilo", + "persian": "کیلو", + "finglish": "kilu" + }, + { + "id": "quantities_and_measures_litre", + "section": "High-frequency language", + "category": "Quantities and measures", + "english": "litre", + "persian": "لیتر", + "finglish": "litr" + }, + { + "id": "quantities_and_measures_metre", + "section": "High-frequency language", + "category": "Quantities and measures", + "english": "metre", + "persian": "متر", + "finglish": "metr" + }, + { + "id": "connecting_words_and", + "section": "High-frequency language", + "category": "Connecting words", + "english": "and", + "persian": "و", + "finglish": "va" + }, + { + "id": "connecting_words_or", + "section": "High-frequency language", + "category": "Connecting words", + "english": "or", + "persian": "یا", + "finglish": "yâ" + }, + { + "id": "connecting_words_but", + "section": "High-frequency language", + "category": "Connecting words", + "english": "but", + "persian": "اما", + "finglish": "ammâ" + }, + { + "id": "connecting_words_because", + "section": "High-frequency language", + "category": "Connecting words", + "english": "because", + "persian": "چون", + "finglish": "chon" + }, + { + "id": "connecting_words_so", + "section": "High-frequency language", + "category": "Connecting words", + "english": "so", + "persian": "پس", + "finglish": "pas" + }, + { + "id": "connecting_words_if", + "section": "High-frequency language", + "category": "Connecting words", + "english": "if", + "persian": "اگر", + "finglish": "agar" + }, + { + "id": "connecting_words_when", + "section": "High-frequency language", + "category": "Connecting words", + "english": "when", + "persian": "وقتی", + "finglish": "vaghti" + }, + { + "id": "connecting_words_while", + "section": "High-frequency language", + "category": "Connecting words", + "english": "while", + "persian": "در حالی که", + "finglish": "dar hâli ke" + }, + { + "id": "connecting_words_although", + "section": "High-frequency language", + "category": "Connecting words", + "english": "although", + "persian": "اگرچه", + "finglish": "agarche" + }, + { + "id": "connecting_words_however", + "section": "High-frequency language", + "category": "Connecting words", + "english": "however", + "persian": "با این حال", + "finglish": "bâ in hâl" + }, + { + "id": "connecting_words_therefore", + "section": "High-frequency language", + "category": "Connecting words", + "english": "therefore", + "persian": "بنابراین", + "finglish": "banâbar-in" + }, + { + "id": "connecting_words_also", + "section": "High-frequency language", + "category": "Connecting words", + "english": "also", + "persian": "همچنین", + "finglish": "hamchenin" + }, + { + "id": "connecting_words_then", + "section": "High-frequency language", + "category": "Connecting words", + "english": "then", + "persian": "سپس", + "finglish": "sepas" + }, + { + "id": "connecting_words_that", + "section": "High-frequency language", + "category": "Connecting words", + "english": "that", + "persian": "که", + "finglish": "ke" + }, + { + "id": "connecting_words_which", + "section": "High-frequency language", + "category": "Connecting words", + "english": "which", + "persian": "که", + "finglish": "ke" + }, + { + "id": "connecting_words_who", + "section": "High-frequency language", + "category": "Connecting words", + "english": "who", + "persian": "که", + "finglish": "ke" + }, + { + "id": "connecting_words_where", + "section": "High-frequency language", + "category": "Connecting words", + "english": "where", + "persian": "جایی که", + "finglish": "jâyi ke" + }, + { + "id": "connecting_words_before", + "section": "High-frequency language", + "category": "Connecting words", + "english": "before", + "persian": "قبل از اینکه", + "finglish": "ghabl az inke" + }, + { + "id": "connecting_words_after", + "section": "High-frequency language", + "category": "Connecting words", + "english": "after", + "persian": "بعد از اینکه", + "finglish": "ba'd az inke" + }, + { + "id": "connecting_words_until", + "section": "High-frequency language", + "category": "Connecting words", + "english": "until", + "persian": "تا اینکه", + "finglish": "tâ inke" + }, + { + "id": "connecting_words_since", + "section": "High-frequency language", + "category": "Connecting words", + "english": "since", + "persian": "از وقتی که", + "finglish": "az vaghti ke" + }, + { + "id": "connecting_words_as", + "section": "High-frequency language", + "category": "Connecting words", + "english": "as", + "persian": "همانطور که", + "finglish": "hamântour ke" + }, + { + "id": "connecting_words_unless", + "section": "High-frequency language", + "category": "Connecting words", + "english": "unless", + "persian": "مگر اینکه", + "finglish": "magar inke" + }, + { + "id": "connecting_words_moreover", + "section": "High-frequency language", + "category": "Connecting words", + "english": "moreover", + "persian": "علاوه بر این", + "finglish": "alâve bar in" + }, + { + "id": "connecting_words_furthermore", + "section": "High-frequency language", + "category": "Connecting words", + "english": "furthermore", + "persian": "به علاوه", + "finglish": "be alâve" + }, + { + "id": "time_expressions_today", + "section": "High-frequency language", + "category": "Time expressions", + "english": "today", + "persian": "امروز", + "finglish": "emruz" + }, + { + "id": "time_expressions_tomorrow", + "section": "High-frequency language", + "category": "Time expressions", + "english": "tomorrow", + "persian": "فردا", + "finglish": "fardâ" + }, + { + "id": "time_expressions_yesterday", + "section": "High-frequency language", + "category": "Time expressions", + "english": "yesterday", + "persian": "دیروز", + "finglish": "diruz" + }, + { + "id": "time_expressions_now", + "section": "High-frequency language", + "category": "Time expressions", + "english": "now", + "persian": "الان", + "finglish": "al'ân" + }, + { + "id": "time_expressions_then", + "section": "High-frequency language", + "category": "Time expressions", + "english": "then", + "persian": "آن موقع", + "finglish": "ân moghe'" + }, + { + "id": "time_expressions_always", + "section": "High-frequency language", + "category": "Time expressions", + "english": "always", + "persian": "همیشه", + "finglish": "hamishe" + }, + { + "id": "time_expressions_never", + "section": "High-frequency language", + "category": "Time expressions", + "english": "never", + "persian": "هرگز", + "finglish": "hargez" + }, + { + "id": "time_expressions_sometimes", + "section": "High-frequency language", + "category": "Time expressions", + "english": "sometimes", + "persian": "گاهی اوقات", + "finglish": "gâhi oghât" + }, + { + "id": "time_expressions_often", + "section": "High-frequency language", + "category": "Time expressions", + "english": "often", + "persian": "اغلب", + "finglish": "aghlab" + }, + { + "id": "time_expressions_already", + "section": "High-frequency language", + "category": "Time expressions", + "english": "already", + "persian": "قبلا", + "finglish": "ghablan" + }, + { + "id": "time_expressions_soon", + "section": "High-frequency language", + "category": "Time expressions", + "english": "soon", + "persian": "به زودی", + "finglish": "be zudi" + }, + { + "id": "time_expressions_still", + "section": "High-frequency language", + "category": "Time expressions", + "english": "still", + "persian": "هنوز", + "finglish": "hanuz" + }, + { + "id": "time_expressions_yet", + "section": "High-frequency language", + "category": "Time expressions", + "english": "yet", + "persian": "هنوز", + "finglish": "hanuz" + }, + { + "id": "time_expressions_ago", + "section": "High-frequency language", + "category": "Time expressions", + "english": "ago", + "persian": "پیش", + "finglish": "pish" + }, + { + "id": "time_expressions_later", + "section": "High-frequency language", + "category": "Time expressions", + "english": "later", + "persian": "بعدا", + "finglish": "ba'dan" + }, + { + "id": "time_expressions_early", + "section": "High-frequency language", + "category": "Time expressions", + "english": "early", + "persian": "زود", + "finglish": "zud" + }, + { + "id": "time_expressions_late", + "section": "High-frequency language", + "category": "Time expressions", + "english": "late", + "persian": "دیر", + "finglish": "dir" + }, + { + "id": "time_expressions_morning", + "section": "High-frequency language", + "category": "Time expressions", + "english": "morning", + "persian": "صبح", + "finglish": "sobh" + }, + { + "id": "time_expressions_afternoon", + "section": "High-frequency language", + "category": "Time expressions", + "english": "afternoon", + "persian": "بعد از ظهر", + "finglish": "ba'd az zohr" + }, + { + "id": "time_expressions_evening", + "section": "High-frequency language", + "category": "Time expressions", + "english": "evening", + "persian": "عصر", + "finglish": "asr" + }, + { + "id": "time_expressions_night", + "section": "High-frequency language", + "category": "Time expressions", + "english": "night", + "persian": "شب", + "finglish": "shab" + }, + { + "id": "time_expressions_midnight", + "section": "High-frequency language", + "category": "Time expressions", + "english": "midnight", + "persian": "نیمه‌شب", + "finglish": "nime-shab" + }, + { + "id": "time_expressions_noon", + "section": "High-frequency language", + "category": "Time expressions", + "english": "noon", + "persian": "ظهر", + "finglish": "zohr" + }, + { + "id": "time_expressions_during", + "section": "High-frequency language", + "category": "Time expressions", + "english": "during", + "persian": "در طول", + "finglish": "dar tul" + }, + { + "id": "time_expressions_since", + "section": "High-frequency language", + "category": "Time expressions", + "english": "since", + "persian": "از", + "finglish": "az" + }, + { + "id": "days_and_months_saturday", + "section": "High-frequency language", + "category": "Days and months", + "english": "Saturday", + "persian": "شنبه", + "finglish": "shanbe" + }, + { + "id": "days_and_months_sunday", + "section": "High-frequency language", + "category": "Days and months", + "english": "Sunday", + "persian": "یکشنبه", + "finglish": "yekshanbe" + }, + { + "id": "days_and_months_monday", + "section": "High-frequency language", + "category": "Days and months", + "english": "Monday", + "persian": "دوشنبه", + "finglish": "doshanbe" + }, + { + "id": "days_and_months_tuesday", + "section": "High-frequency language", + "category": "Days and months", + "english": "Tuesday", + "persian": "سه‌شنبه", + "finglish": "seshanbe" + }, + { + "id": "days_and_months_wednesday", + "section": "High-frequency language", + "category": "Days and months", + "english": "Wednesday", + "persian": "چهارشنبه", + "finglish": "chahârshanbe" + }, + { + "id": "days_and_months_thursday", + "section": "High-frequency language", + "category": "Days and months", + "english": "Thursday", + "persian": "پنجشنبه", + "finglish": "panjshanbe" + }, + { + "id": "days_and_months_friday", + "section": "High-frequency language", + "category": "Days and months", + "english": "Friday", + "persian": "جمعه", + "finglish": "jom'e" + }, + { + "id": "days_and_months_farvardin", + "section": "High-frequency language", + "category": "Days and months", + "english": "Farvardin", + "persian": "فروردین", + "finglish": "farvardin" + }, + { + "id": "days_and_months_ordibehesht", + "section": "High-frequency language", + "category": "Days and months", + "english": "Ordibehesht", + "persian": "اردیبهشت", + "finglish": "ordibehesht" + }, + { + "id": "days_and_months_khordad", + "section": "High-frequency language", + "category": "Days and months", + "english": "Khordad", + "persian": "خرداد", + "finglish": "khordâd" + }, + { + "id": "days_and_months_tir", + "section": "High-frequency language", + "category": "Days and months", + "english": "Tir", + "persian": "تیر", + "finglish": "tir" + }, + { + "id": "days_and_months_mordad", + "section": "High-frequency language", + "category": "Days and months", + "english": "Mordad", + "persian": "مرداد", + "finglish": "mordâd" + }, + { + "id": "days_and_months_shahrivar", + "section": "High-frequency language", + "category": "Days and months", + "english": "Shahrivar", + "persian": "شهریور", + "finglish": "shahrivar" + }, + { + "id": "days_and_months_mehr", + "section": "High-frequency language", + "category": "Days and months", + "english": "Mehr", + "persian": "مهر", + "finglish": "mehr" + }, + { + "id": "days_and_months_aban", + "section": "High-frequency language", + "category": "Days and months", + "english": "Aban", + "persian": "آبان", + "finglish": "âbân" + }, + { + "id": "days_and_months_azar", + "section": "High-frequency language", + "category": "Days and months", + "english": "Azar", + "persian": "آذر", + "finglish": "âzar" + }, + { + "id": "days_and_months_dey", + "section": "High-frequency language", + "category": "Days and months", + "english": "Dey", + "persian": "دی", + "finglish": "dey" + }, + { + "id": "days_and_months_bahman", + "section": "High-frequency language", + "category": "Days and months", + "english": "Bahman", + "persian": "بهمن", + "finglish": "bahman" + }, + { + "id": "days_and_months_esfand", + "section": "High-frequency language", + "category": "Days and months", + "english": "Esfand", + "persian": "اسفند", + "finglish": "esfand" + }, + { + "id": "days_and_months_spring", + "section": "High-frequency language", + "category": "Days and months", + "english": "spring", + "persian": "بهار", + "finglish": "bahâr" + }, + { + "id": "days_and_months_summer", + "section": "High-frequency language", + "category": "Days and months", + "english": "summer", + "persian": "تابستان", + "finglish": "tâbestân" + }, + { + "id": "days_and_months_autumn", + "section": "High-frequency language", + "category": "Days and months", + "english": "autumn", + "persian": "پاییز", + "finglish": "pâyiz" + }, + { + "id": "days_and_months_winter", + "section": "High-frequency language", + "category": "Days and months", + "english": "winter", + "persian": "زمستان", + "finglish": "zemestân" + }, + { + "id": "question_words_who", + "section": "High-frequency language", + "category": "Question words", + "english": "who", + "persian": "کی", + "finglish": "ki" + }, + { + "id": "question_words_what", + "section": "High-frequency language", + "category": "Question words", + "english": "what", + "persian": "چی", + "finglish": "chi" + }, + { + "id": "question_words_when", + "section": "High-frequency language", + "category": "Question words", + "english": "when", + "persian": "کی", + "finglish": "key" + }, + { + "id": "question_words_where", + "section": "High-frequency language", + "category": "Question words", + "english": "where", + "persian": "کجا", + "finglish": "kojâ" + }, + { + "id": "question_words_why", + "section": "High-frequency language", + "category": "Question words", + "english": "why", + "persian": "چرا", + "finglish": "cherâ" + }, + { + "id": "question_words_how", + "section": "High-frequency language", + "category": "Question words", + "english": "how", + "persian": "چطور", + "finglish": "chetor" + }, + { + "id": "question_words_which", + "section": "High-frequency language", + "category": "Question words", + "english": "which", + "persian": "کدام", + "finglish": "kodâm" + }, + { + "id": "question_words_how_much", + "section": "High-frequency language", + "category": "Question words", + "english": "how much", + "persian": "چقدر", + "finglish": "cheghadr" + }, + { + "id": "question_words_how_many", + "section": "High-frequency language", + "category": "Question words", + "english": "how many", + "persian": "چند تا", + "finglish": "chand tâ" + }, + { + "id": "question_words_whose", + "section": "High-frequency language", + "category": "Question words", + "english": "whose", + "persian": "مال کی", + "finglish": "mâl-e ki" + }, + { + "id": "question_words_what_kind_of", + "section": "High-frequency language", + "category": "Question words", + "english": "what kind of", + "persian": "چه نوع", + "finglish": "che now'" + }, + { + "id": "question_words_how_long", + "section": "High-frequency language", + "category": "Question words", + "english": "how long", + "persian": "چه مدت", + "finglish": "che moddat" + }, + { + "id": "useful_expressions_hello", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "hello", + "persian": "سلام", + "finglish": "salâm" + }, + { + "id": "useful_expressions_goodbye", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "goodbye", + "persian": "خداحافظ", + "finglish": "khodâhâfez" + }, + { + "id": "useful_expressions_please", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "please", + "persian": "لطفا", + "finglish": "lotfan" + }, + { + "id": "useful_expressions_thank_you", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "thank you", + "persian": "ممنون", + "finglish": "mamnun" + }, + { + "id": "useful_expressions_youre_welcome", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "you're welcome", + "persian": "خواهش می‌کنم", + "finglish": "khâhesh mikonam" + }, + { + "id": "useful_expressions_excuse_me", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "excuse me", + "persian": "ببخشید", + "finglish": "bebakhshid" + }, + { + "id": "useful_expressions_sorry", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "sorry", + "persian": "متاسفم", + "finglish": "mota'assefam" + }, + { + "id": "useful_expressions_good_morning", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "good morning", + "persian": "صبح بخیر", + "finglish": "sobh bekheyr" + }, + { + "id": "useful_expressions_good_evening", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "good evening", + "persian": "عصر بخیر", + "finglish": "asr bekheyr" + }, + { + "id": "useful_expressions_good_night", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "good night", + "persian": "شب بخیر", + "finglish": "shab bekheyr" + }, + { + "id": "useful_expressions_how_are_you", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "how are you", + "persian": "حالت چطوره", + "finglish": "hâlet chetore" + }, + { + "id": "useful_expressions_im_fine", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "I'm fine", + "persian": "خوبم", + "finglish": "khubam" + }, + { + "id": "useful_expressions_yes", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "yes", + "persian": "بله", + "finglish": "bale" + }, + { + "id": "useful_expressions_no", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "no", + "persian": "نه", + "finglish": "na" + }, + { + "id": "useful_expressions_of_course", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "of course", + "persian": "البته", + "finglish": "albatte" + }, + { + "id": "useful_expressions_congratulations", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "congratulations", + "persian": "تبریک", + "finglish": "tabrik" + }, + { + "id": "useful_expressions_happy_birthday", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "happy birthday", + "persian": "تولدت مبارک", + "finglish": "tavalodet mobârak" + }, + { + "id": "useful_expressions_happy_new_year", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "happy new year", + "persian": "عید نوروز مبارک", + "finglish": "eyd-e nowruz mobârak" + }, + { + "id": "useful_expressions_welcome", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "welcome", + "persian": "خوش آمدید", + "finglish": "khosh âmadid" + }, + { + "id": "useful_expressions_help", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "help", + "persian": "کمک", + "finglish": "komak" + }, + { + "id": "useful_expressions_i_dont_understand", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "I don't understand", + "persian": "نمی‌فهمم", + "finglish": "nemifahmam" + }, + { + "id": "useful_expressions_i_dont_know", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "I don't know", + "persian": "نمی‌دونم", + "finglish": "nemidounam" + }, + { + "id": "useful_expressions_slowly_please", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "slowly please", + "persian": "آهسته لطفا", + "finglish": "âheste lotfan" + }, + { + "id": "useful_expressions_repeat_please", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "repeat please", + "persian": "تکرار کنید لطفا", + "finglish": "tekrâr konid lotfan" + }, + { + "id": "useful_expressions_what_does_this_mean", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "what does this mean", + "persian": "این یعنی چی", + "finglish": "in ya'ni chi" + }, + { + "id": "useful_expressions_may_i", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "may I", + "persian": "اجازه هست", + "finglish": "ejâze hast" + }, + { + "id": "useful_expressions_it_doesnt_matter", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "it doesn't matter", + "persian": "مهم نیست", + "finglish": "mohem nist" + }, + { + "id": "useful_expressions_god_willing", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "God willing", + "persian": "ان‌شاءالله", + "finglish": "inshâ'allâh" + }, + { + "id": "useful_expressions_bless_you", + "section": "High-frequency language", + "category": "Useful expressions", + "english": "bless you", + "persian": "عافیت باشه", + "finglish": "âfiyat bâshe" + }, + { + "id": "countries_iran", + "section": "High-frequency language", + "category": "Countries", + "english": "Iran", + "persian": "ایران", + "finglish": "irân" + }, + { + "id": "countries_afghanistan", + "section": "High-frequency language", + "category": "Countries", + "english": "Afghanistan", + "persian": "افغانستان", + "finglish": "afghânestân" + }, + { + "id": "countries_tajikistan", + "section": "High-frequency language", + "category": "Countries", + "english": "Tajikistan", + "persian": "تاجیکستان", + "finglish": "tâjikestân" + }, + { + "id": "countries_turkey", + "section": "High-frequency language", + "category": "Countries", + "english": "Turkey", + "persian": "ترکیه", + "finglish": "torkiye" + }, + { + "id": "countries_iraq", + "section": "High-frequency language", + "category": "Countries", + "english": "Iraq", + "persian": "عراق", + "finglish": "erâgh" + }, + { + "id": "countries_england", + "section": "High-frequency language", + "category": "Countries", + "english": "England", + "persian": "انگلستان", + "finglish": "engelestân" + }, + { + "id": "countries_france", + "section": "High-frequency language", + "category": "Countries", + "english": "France", + "persian": "فرانسه", + "finglish": "farânse" + }, + { + "id": "countries_germany", + "section": "High-frequency language", + "category": "Countries", + "english": "Germany", + "persian": "آلمان", + "finglish": "âlmân" + }, + { + "id": "countries_spain", + "section": "High-frequency language", + "category": "Countries", + "english": "Spain", + "persian": "اسپانیا", + "finglish": "espâniyâ" + }, + { + "id": "countries_italy", + "section": "High-frequency language", + "category": "Countries", + "english": "Italy", + "persian": "ایتالیا", + "finglish": "itâliyâ" + }, + { + "id": "countries_america", + "section": "High-frequency language", + "category": "Countries", + "english": "America", + "persian": "آمریکا", + "finglish": "âmrikâ" + }, + { + "id": "countries_canada", + "section": "High-frequency language", + "category": "Countries", + "english": "Canada", + "persian": "کانادا", + "finglish": "kânâdâ" + }, + { + "id": "countries_australia", + "section": "High-frequency language", + "category": "Countries", + "english": "Australia", + "persian": "استرالیا", + "finglish": "ostrâliyâ" + }, + { + "id": "countries_china", + "section": "High-frequency language", + "category": "Countries", + "english": "China", + "persian": "چین", + "finglish": "chin" + }, + { + "id": "countries_japan", + "section": "High-frequency language", + "category": "Countries", + "english": "Japan", + "persian": "ژاپن", + "finglish": "zhâpon" + }, + { + "id": "countries_india", + "section": "High-frequency language", + "category": "Countries", + "english": "India", + "persian": "هند", + "finglish": "hend" + }, + { + "id": "countries_russia", + "section": "High-frequency language", + "category": "Countries", + "english": "Russia", + "persian": "روسیه", + "finglish": "rusiye" + }, + { + "id": "countries_pakistan", + "section": "High-frequency language", + "category": "Countries", + "english": "Pakistan", + "persian": "پاکستان", + "finglish": "pâkestân" + }, + { + "id": "countries_saudi_arabia", + "section": "High-frequency language", + "category": "Countries", + "english": "Saudi Arabia", + "persian": "عربستان سعودی", + "finglish": "arabestân-e so'udi" + }, + { + "id": "countries_egypt", + "section": "High-frequency language", + "category": "Countries", + "english": "Egypt", + "persian": "مصر", + "finglish": "mesr" + }, + { + "id": "countries_united_arab_emirates", + "section": "High-frequency language", + "category": "Countries", + "english": "United Arab Emirates", + "persian": "امارات متحده عربی", + "finglish": "emârât-e mottahed-e arabi" + }, + { + "id": "countries_syria", + "section": "High-frequency language", + "category": "Countries", + "english": "Syria", + "persian": "سوریه", + "finglish": "suriye" + }, + { + "id": "countries_lebanon", + "section": "High-frequency language", + "category": "Countries", + "english": "Lebanon", + "persian": "لبنان", + "finglish": "lobnân" + }, + { + "id": "countries_morocco", + "section": "High-frequency language", + "category": "Countries", + "english": "Morocco", + "persian": "مراکش", + "finglish": "marâkesh" + }, + { + "id": "countries_brazil", + "section": "High-frequency language", + "category": "Countries", + "english": "Brazil", + "persian": "برزیل", + "finglish": "berezil" + }, + { + "id": "nationalities_iranian", + "section": "High-frequency language", + "category": "Nationalities", + "english": "Iranian", + "persian": "ایرانی", + "finglish": "irâni" + }, + { + "id": "nationalities_afghan", + "section": "High-frequency language", + "category": "Nationalities", + "english": "Afghan", + "persian": "افغان", + "finglish": "afghân" + }, + { + "id": "nationalities_english", + "section": "High-frequency language", + "category": "Nationalities", + "english": "English", + "persian": "انگلیسی", + "finglish": "engelisi" + }, + { + "id": "nationalities_french", + "section": "High-frequency language", + "category": "Nationalities", + "english": "French", + "persian": "فرانسوی", + "finglish": "farânsavi" + }, + { + "id": "nationalities_german", + "section": "High-frequency language", + "category": "Nationalities", + "english": "German", + "persian": "آلمانی", + "finglish": "âlmâni" + }, + { + "id": "nationalities_american", + "section": "High-frequency language", + "category": "Nationalities", + "english": "American", + "persian": "آمریکایی", + "finglish": "âmrikâyi" + }, + { + "id": "nationalities_turkish", + "section": "High-frequency language", + "category": "Nationalities", + "english": "Turkish", + "persian": "ترک", + "finglish": "tork" + }, + { + "id": "nationalities_arab", + "section": "High-frequency language", + "category": "Nationalities", + "english": "Arab", + "persian": "عرب", + "finglish": "arab" + }, + { + "id": "nationalities_indian", + "section": "High-frequency language", + "category": "Nationalities", + "english": "Indian", + "persian": "هندی", + "finglish": "hendi" + }, + { + "id": "nationalities_chinese", + "section": "High-frequency language", + "category": "Nationalities", + "english": "Chinese", + "persian": "چینی", + "finglish": "chini" + }, + { + "id": "nationalities_japanese", + "section": "High-frequency language", + "category": "Nationalities", + "english": "Japanese", + "persian": "ژاپنی", + "finglish": "zhâponi" + }, + { + "id": "nationalities_russian", + "section": "High-frequency language", + "category": "Nationalities", + "english": "Russian", + "persian": "روسی", + "finglish": "rusi" + }, + { + "id": "nationalities_italian", + "section": "High-frequency language", + "category": "Nationalities", + "english": "Italian", + "persian": "ایتالیایی", + "finglish": "itâliyâyi" + }, + { + "id": "nationalities_spanish", + "section": "High-frequency language", + "category": "Nationalities", + "english": "Spanish", + "persian": "اسپانیایی", + "finglish": "espâniyâyi" + }, + { + "id": "nationalities_pakistani", + "section": "High-frequency language", + "category": "Nationalities", + "english": "Pakistani", + "persian": "پاکستانی", + "finglish": "pâkestâni" + }, + { + "id": "nationalities_australian", + "section": "High-frequency language", + "category": "Nationalities", + "english": "Australian", + "persian": "استرالیایی", + "finglish": "ostrâliyâyi" + }, + { + "id": "nationalities_canadian", + "section": "High-frequency language", + "category": "Nationalities", + "english": "Canadian", + "persian": "کانادایی", + "finglish": "kânâdâyi" + }, + { + "id": "nationalities_iraqi", + "section": "High-frequency language", + "category": "Nationalities", + "english": "Iraqi", + "persian": "عراقی", + "finglish": "erâghi" + }, + { + "id": "nationalities_egyptian", + "section": "High-frequency language", + "category": "Nationalities", + "english": "Egyptian", + "persian": "مصری", + "finglish": "mesri" + }, + { + "id": "nationalities_brazilian", + "section": "High-frequency language", + "category": "Nationalities", + "english": "Brazilian", + "persian": "برزیلی", + "finglish": "berezili" + }, + { + "id": "social_conventions_greeting_someone", + "section": "High-frequency language", + "category": "Social conventions", + "english": "greeting someone", + "persian": "سلام و احوالپرسی", + "finglish": "salâm va ahvâlporsi" + }, + { + "id": "social_conventions_introducing_yourself", + "section": "High-frequency language", + "category": "Social conventions", + "english": "introducing yourself", + "persian": "معرفی خود", + "finglish": "mo'arrefi-ye khod" + }, + { + "id": "social_conventions_asking_about_health", + "section": "High-frequency language", + "category": "Social conventions", + "english": "asking about health", + "persian": "احوالپرسی", + "finglish": "ahvâlporsi" + }, + { + "id": "social_conventions_thanking", + "section": "High-frequency language", + "category": "Social conventions", + "english": "thanking", + "persian": "تشکر کردن", + "finglish": "tashakkor kardan" + }, + { + "id": "social_conventions_apologizing", + "section": "High-frequency language", + "category": "Social conventions", + "english": "apologizing", + "persian": "عذرخواهی کردن", + "finglish": "ozrkhâhi kardan" + }, + { + "id": "social_conventions_congratulating", + "section": "High-frequency language", + "category": "Social conventions", + "english": "congratulating", + "persian": "تبریک گفتن", + "finglish": "tabrik goftan" + }, + { + "id": "social_conventions_expressing_condolence", + "section": "High-frequency language", + "category": "Social conventions", + "english": "expressing condolence", + "persian": "تسلیت گفتن", + "finglish": "tasliyat goftan" + }, + { + "id": "social_conventions_saying_goodbye", + "section": "High-frequency language", + "category": "Social conventions", + "english": "saying goodbye", + "persian": "خداحافظی کردن", + "finglish": "khodâhâfezi kardan" + }, + { + "id": "social_conventions_welcoming_guests", + "section": "High-frequency language", + "category": "Social conventions", + "english": "welcoming guests", + "persian": "خوشامدگویی", + "finglish": "khosh-âmad-guyi" + }, + { + "id": "social_conventions_offering_food", + "section": "High-frequency language", + "category": "Social conventions", + "english": "offering food", + "persian": "تعارف کردن غذا", + "finglish": "ta'ârof kardan-e ghazâ" + }, + { + "id": "social_conventions_accepting_an_offer", + "section": "High-frequency language", + "category": "Social conventions", + "english": "accepting an offer", + "persian": "قبول کردن", + "finglish": "ghabul kardan" + }, + { + "id": "social_conventions_declining_an_offer", + "section": "High-frequency language", + "category": "Social conventions", + "english": "declining an offer", + "persian": "رد کردن", + "finglish": "rad kardan" + }, + { + "id": "social_conventions_asking_permission", + "section": "High-frequency language", + "category": "Social conventions", + "english": "asking permission", + "persian": "اجازه خواستن", + "finglish": "ejâze khâstan" + }, + { + "id": "social_conventions_making_a_request", + "section": "High-frequency language", + "category": "Social conventions", + "english": "making a request", + "persian": "درخواست کردن", + "finglish": "darkhâst kardan" + }, + { + "id": "social_conventions_showing_respect", + "section": "High-frequency language", + "category": "Social conventions", + "english": "showing respect", + "persian": "احترام گذاشتن", + "finglish": "ehterâm gozâshtan" + }, + { + "id": "family_members_father", + "section": "Topic-specific vocabulary", + "category": "Family members", + "english": "father", + "persian": "پدر", + "finglish": "pedar" + }, + { + "id": "family_members_mother", + "section": "Topic-specific vocabulary", + "category": "Family members", + "english": "mother", + "persian": "مادر", + "finglish": "mâdar" + }, + { + "id": "family_members_brother", + "section": "Topic-specific vocabulary", + "category": "Family members", + "english": "brother", + "persian": "برادر", + "finglish": "barâdar" + }, + { + "id": "family_members_sister", + "section": "Topic-specific vocabulary", + "category": "Family members", + "english": "sister", + "persian": "خواهر", + "finglish": "khâhar" + }, + { + "id": "family_members_son", + "section": "Topic-specific vocabulary", + "category": "Family members", + "english": "son", + "persian": "پسر", + "finglish": "pesar" + }, + { + "id": "family_members_daughter", + "section": "Topic-specific vocabulary", + "category": "Family members", + "english": "daughter", + "persian": "دختر", + "finglish": "dokhtar" + }, + { + "id": "family_members_grandfather", + "section": "Topic-specific vocabulary", + "category": "Family members", + "english": "grandfather", + "persian": "پدربزرگ", + "finglish": "pedar-bozorg" + }, + { + "id": "family_members_grandmother", + "section": "Topic-specific vocabulary", + "category": "Family members", + "english": "grandmother", + "persian": "مادربزرگ", + "finglish": "mâdar-bozorg" + }, + { + "id": "family_members_uncle", + "section": "Topic-specific vocabulary", + "category": "Family members", + "english": "uncle", + "persian": "عمو / دایی", + "finglish": "amu / dâyi" + }, + { + "id": "family_members_aunt", + "section": "Topic-specific vocabulary", + "category": "Family members", + "english": "aunt", + "persian": "عمه / خاله", + "finglish": "amme / khâle" + }, + { + "id": "family_members_cousin", + "section": "Topic-specific vocabulary", + "category": "Family members", + "english": "cousin", + "persian": "پسرعمو / دخترعمو", + "finglish": "pesar-amu / dokhtar-amu" + }, + { + "id": "family_members_husband", + "section": "Topic-specific vocabulary", + "category": "Family members", + "english": "husband", + "persian": "شوهر", + "finglish": "showhar" + }, + { + "id": "family_members_wife", + "section": "Topic-specific vocabulary", + "category": "Family members", + "english": "wife", + "persian": "زن / همسر", + "finglish": "zan / hamsar" + }, + { + "id": "family_members_family", + "section": "Topic-specific vocabulary", + "category": "Family members", + "english": "family", + "persian": "خانواده", + "finglish": "khânevâde" + }, + { + "id": "family_members_child", + "section": "Topic-specific vocabulary", + "category": "Family members", + "english": "child", + "persian": "بچه", + "finglish": "bachche" + }, + { + "id": "family_members_baby", + "section": "Topic-specific vocabulary", + "category": "Family members", + "english": "baby", + "persian": "نوزاد", + "finglish": "nowzâd" + }, + { + "id": "physical_descriptions_hair", + "section": "Topic-specific vocabulary", + "category": "Physical descriptions", + "english": "hair", + "persian": "مو", + "finglish": "mu" + }, + { + "id": "physical_descriptions_eye", + "section": "Topic-specific vocabulary", + "category": "Physical descriptions", + "english": "eye", + "persian": "چشم", + "finglish": "cheshm" + }, + { + "id": "physical_descriptions_tall", + "section": "Topic-specific vocabulary", + "category": "Physical descriptions", + "english": "tall", + "persian": "بلند قد", + "finglish": "boland-ghad" + }, + { + "id": "physical_descriptions_short_(height)", + "section": "Topic-specific vocabulary", + "category": "Physical descriptions", + "english": "short (height)", + "persian": "کوتاه قد", + "finglish": "kutâh-ghad" + }, + { + "id": "physical_descriptions_thin", + "section": "Topic-specific vocabulary", + "category": "Physical descriptions", + "english": "thin", + "persian": "لاغر", + "finglish": "lâghar" + }, + { + "id": "physical_descriptions_fat", + "section": "Topic-specific vocabulary", + "category": "Physical descriptions", + "english": "fat", + "persian": "چاق", + "finglish": "châgh" + }, + { + "id": "physical_descriptions_handsome", + "section": "Topic-specific vocabulary", + "category": "Physical descriptions", + "english": "handsome", + "persian": "خوش‌تیپ", + "finglish": "khosh-tip" + }, + { + "id": "physical_descriptions_curly_hair", + "section": "Topic-specific vocabulary", + "category": "Physical descriptions", + "english": "curly hair", + "persian": "موی فرفری", + "finglish": "mu-ye ferferi" + }, + { + "id": "physical_descriptions_straight_hair", + "section": "Topic-specific vocabulary", + "category": "Physical descriptions", + "english": "straight hair", + "persian": "موی صاف", + "finglish": "mu-ye sâf" + }, + { + "id": "physical_descriptions_beard", + "section": "Topic-specific vocabulary", + "category": "Physical descriptions", + "english": "beard", + "persian": "ریش", + "finglish": "rish" + }, + { + "id": "personality_kind", + "section": "Topic-specific vocabulary", + "category": "Personality", + "english": "kind", + "persian": "مهربان", + "finglish": "mehrabân" + }, + { + "id": "personality_shy", + "section": "Topic-specific vocabulary", + "category": "Personality", + "english": "shy", + "persian": "خجالتی", + "finglish": "khejâlati" + }, + { + "id": "personality_generous", + "section": "Topic-specific vocabulary", + "category": "Personality", + "english": "generous", + "persian": "سخاوتمند", + "finglish": "sakhâvatmand" + }, + { + "id": "personality_patient", + "section": "Topic-specific vocabulary", + "category": "Personality", + "english": "patient", + "persian": "صبور", + "finglish": "sabur" + }, + { + "id": "personality_cheerful", + "section": "Topic-specific vocabulary", + "category": "Personality", + "english": "cheerful", + "persian": "شاد", + "finglish": "shâd" + }, + { + "id": "personality_hard-working", + "section": "Topic-specific vocabulary", + "category": "Personality", + "english": "hard-working", + "persian": "زحمتکش", + "finglish": "zahmatkesh" + }, + { + "id": "personality_honest", + "section": "Topic-specific vocabulary", + "category": "Personality", + "english": "honest", + "persian": "صادق", + "finglish": "sâdegh" + }, + { + "id": "personality_selfish", + "section": "Topic-specific vocabulary", + "category": "Personality", + "english": "selfish", + "persian": "خودخواه", + "finglish": "khod-khâh" + }, + { + "id": "personality_reliable", + "section": "Topic-specific vocabulary", + "category": "Personality", + "english": "reliable", + "persian": "قابل اعتماد", + "finglish": "ghâbel-e e'temâd" + }, + { + "id": "personality_stubborn", + "section": "Topic-specific vocabulary", + "category": "Personality", + "english": "stubborn", + "persian": "لجباز", + "finglish": "lajbâz" + }, + { + "id": "daily_routine_to_wake_up", + "section": "Topic-specific vocabulary", + "category": "Daily routine", + "english": "to wake up", + "persian": "بیدار شدن", + "finglish": "bidâr shodan" + }, + { + "id": "daily_routine_to_get_dressed", + "section": "Topic-specific vocabulary", + "category": "Daily routine", + "english": "to get dressed", + "persian": "لباس پوشیدن", + "finglish": "lebâs pushidan" + }, + { + "id": "daily_routine_to_have_breakfast", + "section": "Topic-specific vocabulary", + "category": "Daily routine", + "english": "to have breakfast", + "persian": "صبحانه خوردن", + "finglish": "sobhâne khordan" + }, + { + "id": "daily_routine_to_go_to_school", + "section": "Topic-specific vocabulary", + "category": "Daily routine", + "english": "to go to school", + "persian": "به مدرسه رفتن", + "finglish": "be madrese raftan" + }, + { + "id": "daily_routine_to_have_lunch", + "section": "Topic-specific vocabulary", + "category": "Daily routine", + "english": "to have lunch", + "persian": "ناهار خوردن", + "finglish": "nâhâr khordan" + }, + { + "id": "daily_routine_to_do_homework", + "section": "Topic-specific vocabulary", + "category": "Daily routine", + "english": "to do homework", + "persian": "تکلیف انجام دادن", + "finglish": "taklif anjâm dâdan" + }, + { + "id": "daily_routine_to_have_dinner", + "section": "Topic-specific vocabulary", + "category": "Daily routine", + "english": "to have dinner", + "persian": "شام خوردن", + "finglish": "shâm khordan" + }, + { + "id": "daily_routine_to_brush_teeth", + "section": "Topic-specific vocabulary", + "category": "Daily routine", + "english": "to brush teeth", + "persian": "مسواک زدن", + "finglish": "mesvâk zadan" + }, + { + "id": "daily_routine_to_go_to_bed", + "section": "Topic-specific vocabulary", + "category": "Daily routine", + "english": "to go to bed", + "persian": "به رختخواب رفتن", + "finglish": "be rakhtekhâb raftan" + }, + { + "id": "daily_routine_to_take_a_shower", + "section": "Topic-specific vocabulary", + "category": "Daily routine", + "english": "to take a shower", + "persian": "دوش گرفتن", + "finglish": "dush gereftan" + }, + { + "id": "food_and_drink_bread", + "section": "Topic-specific vocabulary", + "category": "Food and drink", + "english": "bread", + "persian": "نان", + "finglish": "nân" + }, + { + "id": "food_and_drink_rice", + "section": "Topic-specific vocabulary", + "category": "Food and drink", + "english": "rice", + "persian": "برنج", + "finglish": "berenj" + }, + { + "id": "food_and_drink_meat", + "section": "Topic-specific vocabulary", + "category": "Food and drink", + "english": "meat", + "persian": "گوشت", + "finglish": "gusht" + }, + { + "id": "food_and_drink_chicken", + "section": "Topic-specific vocabulary", + "category": "Food and drink", + "english": "chicken", + "persian": "مرغ", + "finglish": "morgh" + }, + { + "id": "food_and_drink_fish", + "section": "Topic-specific vocabulary", + "category": "Food and drink", + "english": "fish", + "persian": "ماهی", + "finglish": "mâhi" + }, + { + "id": "food_and_drink_fruit", + "section": "Topic-specific vocabulary", + "category": "Food and drink", + "english": "fruit", + "persian": "میوه", + "finglish": "mive" + }, + { + "id": "food_and_drink_vegetable", + "section": "Topic-specific vocabulary", + "category": "Food and drink", + "english": "vegetable", + "persian": "سبزیجات", + "finglish": "sabzijât" + }, + { + "id": "food_and_drink_water", + "section": "Topic-specific vocabulary", + "category": "Food and drink", + "english": "water", + "persian": "آب", + "finglish": "âb" + }, + { + "id": "food_and_drink_tea", + "section": "Topic-specific vocabulary", + "category": "Food and drink", + "english": "tea", + "persian": "چای", + "finglish": "châi" + }, + { + "id": "food_and_drink_milk", + "section": "Topic-specific vocabulary", + "category": "Food and drink", + "english": "milk", + "persian": "شیر", + "finglish": "shir" + }, + { + "id": "food_and_drink_cheese", + "section": "Topic-specific vocabulary", + "category": "Food and drink", + "english": "cheese", + "persian": "پنیر", + "finglish": "panir" + }, + { + "id": "food_and_drink_egg", + "section": "Topic-specific vocabulary", + "category": "Food and drink", + "english": "egg", + "persian": "تخم‌مرغ", + "finglish": "tokhm-e morgh" + }, + { + "id": "food_and_drink_sugar", + "section": "Topic-specific vocabulary", + "category": "Food and drink", + "english": "sugar", + "persian": "شکر", + "finglish": "shekar" + }, + { + "id": "food_and_drink_salt", + "section": "Topic-specific vocabulary", + "category": "Food and drink", + "english": "salt", + "persian": "نمک", + "finglish": "namak" + }, + { + "id": "food_and_drink_kebab", + "section": "Topic-specific vocabulary", + "category": "Food and drink", + "english": "kebab", + "persian": "کباب", + "finglish": "kabâb" + }, + { + "id": "food_and_drink_yogurt", + "section": "Topic-specific vocabulary", + "category": "Food and drink", + "english": "yogurt", + "persian": "ماست", + "finglish": "mâst" + }, + { + "id": "food_and_drink_soup", + "section": "Topic-specific vocabulary", + "category": "Food and drink", + "english": "soup", + "persian": "سوپ", + "finglish": "sup" + }, + { + "id": "food_and_drink_salad", + "section": "Topic-specific vocabulary", + "category": "Food and drink", + "english": "salad", + "persian": "سالاد", + "finglish": "sâlâd" + }, + { + "id": "food_and_drink_cake", + "section": "Topic-specific vocabulary", + "category": "Food and drink", + "english": "cake", + "persian": "کیک", + "finglish": "keyk" + }, + { + "id": "food_and_drink_ice_cream", + "section": "Topic-specific vocabulary", + "category": "Food and drink", + "english": "ice cream", + "persian": "بستنی", + "finglish": "bastani" + }, + { + "id": "celebrations_nowruz", + "section": "Topic-specific vocabulary", + "category": "Celebrations", + "english": "Nowruz", + "persian": "نوروز", + "finglish": "nowruz" + }, + { + "id": "celebrations_haft-sin", + "section": "Topic-specific vocabulary", + "category": "Celebrations", + "english": "Haft-sin", + "persian": "هفت‌سین", + "finglish": "haft-sin" + }, + { + "id": "celebrations_chaharshanbe_suri", + "section": "Topic-specific vocabulary", + "category": "Celebrations", + "english": "Chaharshanbe Suri", + "persian": "چهارشنبه‌سوری", + "finglish": "chahârshanbe-suri" + }, + { + "id": "celebrations_yalda_night", + "section": "Topic-specific vocabulary", + "category": "Celebrations", + "english": "Yalda night", + "persian": "شب یلدا", + "finglish": "shab-e yaldâ" + }, + { + "id": "celebrations_sizdah_bedar", + "section": "Topic-specific vocabulary", + "category": "Celebrations", + "english": "Sizdah Bedar", + "persian": "سیزده‌بدر", + "finglish": "sizdah-bedar" + }, + { + "id": "celebrations_celebration", + "section": "Topic-specific vocabulary", + "category": "Celebrations", + "english": "celebration", + "persian": "جشن", + "finglish": "jashn" + }, + { + "id": "celebrations_gift", + "section": "Topic-specific vocabulary", + "category": "Celebrations", + "english": "gift", + "persian": "هدیه", + "finglish": "hediye" + }, + { + "id": "celebrations_holiday", + "section": "Topic-specific vocabulary", + "category": "Celebrations", + "english": "holiday", + "persian": "تعطیلات", + "finglish": "ta'tilât" + }, + { + "id": "celebrations_tradition", + "section": "Topic-specific vocabulary", + "category": "Celebrations", + "english": "tradition", + "persian": "سنت", + "finglish": "sonnat" + }, + { + "id": "celebrations_fireworks", + "section": "Topic-specific vocabulary", + "category": "Celebrations", + "english": "fireworks", + "persian": "آتش‌بازی", + "finglish": "âtash-bâzi" + }, + { + "id": "house_and_home_house", + "section": "Topic-specific vocabulary", + "category": "House and home", + "english": "house", + "persian": "خانه", + "finglish": "khâne" + }, + { + "id": "house_and_home_room", + "section": "Topic-specific vocabulary", + "category": "House and home", + "english": "room", + "persian": "اتاق", + "finglish": "otâgh" + }, + { + "id": "house_and_home_kitchen", + "section": "Topic-specific vocabulary", + "category": "House and home", + "english": "kitchen", + "persian": "آشپزخانه", + "finglish": "âshpaz-khâne" + }, + { + "id": "house_and_home_bathroom", + "section": "Topic-specific vocabulary", + "category": "House and home", + "english": "bathroom", + "persian": "حمام", + "finglish": "hammâm" + }, + { + "id": "house_and_home_bedroom", + "section": "Topic-specific vocabulary", + "category": "House and home", + "english": "bedroom", + "persian": "اتاق خواب", + "finglish": "otâgh-e khâb" + }, + { + "id": "house_and_home_living_room", + "section": "Topic-specific vocabulary", + "category": "House and home", + "english": "living room", + "persian": "اتاق نشیمن", + "finglish": "otâgh-e neshiman" + }, + { + "id": "house_and_home_garden", + "section": "Topic-specific vocabulary", + "category": "House and home", + "english": "garden", + "persian": "باغ", + "finglish": "bâgh" + }, + { + "id": "house_and_home_door", + "section": "Topic-specific vocabulary", + "category": "House and home", + "english": "door", + "persian": "در", + "finglish": "dar" + }, + { + "id": "house_and_home_window", + "section": "Topic-specific vocabulary", + "category": "House and home", + "english": "window", + "persian": "پنجره", + "finglish": "panjere" + }, + { + "id": "house_and_home_floor", + "section": "Topic-specific vocabulary", + "category": "House and home", + "english": "floor", + "persian": "طبقه", + "finglish": "tabaghe" + }, + { + "id": "house_and_home_wall", + "section": "Topic-specific vocabulary", + "category": "House and home", + "english": "wall", + "persian": "دیوار", + "finglish": "divâr" + }, + { + "id": "house_and_home_roof", + "section": "Topic-specific vocabulary", + "category": "House and home", + "english": "roof", + "persian": "سقف", + "finglish": "saghf" + }, + { + "id": "house_and_home_stairs", + "section": "Topic-specific vocabulary", + "category": "House and home", + "english": "stairs", + "persian": "پله", + "finglish": "pelle" + }, + { + "id": "house_and_home_furniture", + "section": "Topic-specific vocabulary", + "category": "House and home", + "english": "furniture", + "persian": "مبل", + "finglish": "mobl" + }, + { + "id": "house_and_home_table", + "section": "Topic-specific vocabulary", + "category": "House and home", + "english": "table", + "persian": "میز", + "finglish": "miz" + }, + { + "id": "house_and_home_chair", + "section": "Topic-specific vocabulary", + "category": "House and home", + "english": "chair", + "persian": "صندلی", + "finglish": "sandali" + }, + { + "id": "places_in_town_school", + "section": "Topic-specific vocabulary", + "category": "Places in town", + "english": "school", + "persian": "مدرسه", + "finglish": "madrese" + }, + { + "id": "places_in_town_hospital", + "section": "Topic-specific vocabulary", + "category": "Places in town", + "english": "hospital", + "persian": "بیمارستان", + "finglish": "bimârestân" + }, + { + "id": "places_in_town_mosque", + "section": "Topic-specific vocabulary", + "category": "Places in town", + "english": "mosque", + "persian": "مسجد", + "finglish": "masjed" + }, + { + "id": "places_in_town_park", + "section": "Topic-specific vocabulary", + "category": "Places in town", + "english": "park", + "persian": "پارک", + "finglish": "pârk" + }, + { + "id": "places_in_town_library", + "section": "Topic-specific vocabulary", + "category": "Places in town", + "english": "library", + "persian": "کتابخانه", + "finglish": "ketâb-khâne" + }, + { + "id": "places_in_town_shop", + "section": "Topic-specific vocabulary", + "category": "Places in town", + "english": "shop", + "persian": "مغازه", + "finglish": "maghâze" + }, + { + "id": "places_in_town_market", + "section": "Topic-specific vocabulary", + "category": "Places in town", + "english": "market", + "persian": "بازار", + "finglish": "bâzâr" + }, + { + "id": "places_in_town_bank", + "section": "Topic-specific vocabulary", + "category": "Places in town", + "english": "bank", + "persian": "بانک", + "finglish": "bânk" + }, + { + "id": "places_in_town_restaurant", + "section": "Topic-specific vocabulary", + "category": "Places in town", + "english": "restaurant", + "persian": "رستوران", + "finglish": "restorân" + }, + { + "id": "places_in_town_pharmacy", + "section": "Topic-specific vocabulary", + "category": "Places in town", + "english": "pharmacy", + "persian": "داروخانه", + "finglish": "dâru-khâne" + }, + { + "id": "places_in_town_post_office", + "section": "Topic-specific vocabulary", + "category": "Places in town", + "english": "post office", + "persian": "اداره پست", + "finglish": "edâre-ye post" + }, + { + "id": "places_in_town_cinema", + "section": "Topic-specific vocabulary", + "category": "Places in town", + "english": "cinema", + "persian": "سینما", + "finglish": "sinamâ" + }, + { + "id": "places_in_town_museum", + "section": "Topic-specific vocabulary", + "category": "Places in town", + "english": "museum", + "persian": "موزه", + "finglish": "muze" + }, + { + "id": "places_in_town_street", + "section": "Topic-specific vocabulary", + "category": "Places in town", + "english": "street", + "persian": "خیابان", + "finglish": "khiyâbân" + }, + { + "id": "places_in_town_square", + "section": "Topic-specific vocabulary", + "category": "Places in town", + "english": "square", + "persian": "میدان", + "finglish": "meydân" + }, + { + "id": "shopping_to_buy", + "section": "Topic-specific vocabulary", + "category": "Shopping", + "english": "to buy", + "persian": "خریدن", + "finglish": "kharidan" + }, + { + "id": "shopping_to_sell", + "section": "Topic-specific vocabulary", + "category": "Shopping", + "english": "to sell", + "persian": "فروختن", + "finglish": "foroukhtan" + }, + { + "id": "shopping_price", + "section": "Topic-specific vocabulary", + "category": "Shopping", + "english": "price", + "persian": "قیمت", + "finglish": "gheymat" + }, + { + "id": "shopping_money", + "section": "Topic-specific vocabulary", + "category": "Shopping", + "english": "money", + "persian": "پول", + "finglish": "pul" + }, + { + "id": "shopping_cash", + "section": "Topic-specific vocabulary", + "category": "Shopping", + "english": "cash", + "persian": "نقد", + "finglish": "naghd" + }, + { + "id": "shopping_receipt", + "section": "Topic-specific vocabulary", + "category": "Shopping", + "english": "receipt", + "persian": "رسید", + "finglish": "resid" + }, + { + "id": "shopping_discount", + "section": "Topic-specific vocabulary", + "category": "Shopping", + "english": "discount", + "persian": "تخفیف", + "finglish": "takhfif" + }, + { + "id": "shopping_size", + "section": "Topic-specific vocabulary", + "category": "Shopping", + "english": "size", + "persian": "اندازه", + "finglish": "andâze" + }, + { + "id": "shopping_colour", + "section": "Topic-specific vocabulary", + "category": "Shopping", + "english": "colour", + "persian": "رنگ", + "finglish": "rang" + }, + { + "id": "shopping_bag", + "section": "Topic-specific vocabulary", + "category": "Shopping", + "english": "bag", + "persian": "کیف", + "finglish": "kif" + }, + { + "id": "shopping_clothes", + "section": "Topic-specific vocabulary", + "category": "Shopping", + "english": "clothes", + "persian": "لباس", + "finglish": "lebâs" + }, + { + "id": "shopping_shoes", + "section": "Topic-specific vocabulary", + "category": "Shopping", + "english": "shoes", + "persian": "کفش", + "finglish": "kafsh" + }, + { + "id": "weather_weather", + "section": "Topic-specific vocabulary", + "category": "Weather", + "english": "weather", + "persian": "هوا", + "finglish": "havâ" + }, + { + "id": "weather_sun", + "section": "Topic-specific vocabulary", + "category": "Weather", + "english": "sun", + "persian": "خورشید", + "finglish": "khorshid" + }, + { + "id": "weather_rain", + "section": "Topic-specific vocabulary", + "category": "Weather", + "english": "rain", + "persian": "باران", + "finglish": "bârân" + }, + { + "id": "weather_snow", + "section": "Topic-specific vocabulary", + "category": "Weather", + "english": "snow", + "persian": "برف", + "finglish": "barf" + }, + { + "id": "weather_wind", + "section": "Topic-specific vocabulary", + "category": "Weather", + "english": "wind", + "persian": "باد", + "finglish": "bâd" + }, + { + "id": "weather_cloud", + "section": "Topic-specific vocabulary", + "category": "Weather", + "english": "cloud", + "persian": "ابر", + "finglish": "abr" + }, + { + "id": "weather_hot", + "section": "Topic-specific vocabulary", + "category": "Weather", + "english": "hot", + "persian": "گرم", + "finglish": "garm" + }, + { + "id": "weather_cold", + "section": "Topic-specific vocabulary", + "category": "Weather", + "english": "cold", + "persian": "سرد", + "finglish": "sard" + }, + { + "id": "weather_warm", + "section": "Topic-specific vocabulary", + "category": "Weather", + "english": "warm", + "persian": "ملایم", + "finglish": "molâyem" + }, + { + "id": "weather_sunny", + "section": "Topic-specific vocabulary", + "category": "Weather", + "english": "sunny", + "persian": "آفتابی", + "finglish": "âftâbi" + }, + { + "id": "weather_cloudy", + "section": "Topic-specific vocabulary", + "category": "Weather", + "english": "cloudy", + "persian": "ابری", + "finglish": "abri" + }, + { + "id": "weather_rainy", + "section": "Topic-specific vocabulary", + "category": "Weather", + "english": "rainy", + "persian": "بارانی", + "finglish": "bârâni" + }, + { + "id": "weather_temperature", + "section": "Topic-specific vocabulary", + "category": "Weather", + "english": "temperature", + "persian": "دما", + "finglish": "damâ" + }, + { + "id": "weather_season", + "section": "Topic-specific vocabulary", + "category": "Weather", + "english": "season", + "persian": "فصل", + "finglish": "fasl" + }, + { + "id": "environment_nature", + "section": "Topic-specific vocabulary", + "category": "Environment", + "english": "nature", + "persian": "طبیعت", + "finglish": "tabi'at" + }, + { + "id": "environment_tree", + "section": "Topic-specific vocabulary", + "category": "Environment", + "english": "tree", + "persian": "درخت", + "finglish": "derakht" + }, + { + "id": "environment_flower", + "section": "Topic-specific vocabulary", + "category": "Environment", + "english": "flower", + "persian": "گل", + "finglish": "gol" + }, + { + "id": "environment_river", + "section": "Topic-specific vocabulary", + "category": "Environment", + "english": "river", + "persian": "رودخانه", + "finglish": "rudkhâne" + }, + { + "id": "environment_mountain", + "section": "Topic-specific vocabulary", + "category": "Environment", + "english": "mountain", + "persian": "کوه", + "finglish": "kuh" + }, + { + "id": "environment_sea", + "section": "Topic-specific vocabulary", + "category": "Environment", + "english": "sea", + "persian": "دریا", + "finglish": "daryâ" + }, + { + "id": "environment_forest", + "section": "Topic-specific vocabulary", + "category": "Environment", + "english": "forest", + "persian": "جنگل", + "finglish": "jangal" + }, + { + "id": "environment_desert", + "section": "Topic-specific vocabulary", + "category": "Environment", + "english": "desert", + "persian": "بیابان", + "finglish": "biyâbân" + }, + { + "id": "environment_animal", + "section": "Topic-specific vocabulary", + "category": "Environment", + "english": "animal", + "persian": "حیوان", + "finglish": "heyvân" + }, + { + "id": "environment_bird", + "section": "Topic-specific vocabulary", + "category": "Environment", + "english": "bird", + "persian": "پرنده", + "finglish": "parande" + }, + { + "id": "environment_pollution", + "section": "Topic-specific vocabulary", + "category": "Environment", + "english": "pollution", + "persian": "آلودگی", + "finglish": "âludegi" + }, + { + "id": "environment_recycling", + "section": "Topic-specific vocabulary", + "category": "Environment", + "english": "recycling", + "persian": "بازیافت", + "finglish": "bâzyâft" + }, + { + "id": "environment_environment", + "section": "Topic-specific vocabulary", + "category": "Environment", + "english": "environment", + "persian": "محیط زیست", + "finglish": "mohit-e zist" + }, + { + "id": "environment_earth", + "section": "Topic-specific vocabulary", + "category": "Environment", + "english": "earth", + "persian": "زمین", + "finglish": "zamin" + }, + { + "id": "school_subjects_mathematics", + "section": "Topic-specific vocabulary", + "category": "School subjects", + "english": "mathematics", + "persian": "ریاضی", + "finglish": "riyâzi" + }, + { + "id": "school_subjects_science", + "section": "Topic-specific vocabulary", + "category": "School subjects", + "english": "science", + "persian": "علوم", + "finglish": "olum" + }, + { + "id": "school_subjects_history", + "section": "Topic-specific vocabulary", + "category": "School subjects", + "english": "history", + "persian": "تاریخ", + "finglish": "târikh" + }, + { + "id": "school_subjects_geography", + "section": "Topic-specific vocabulary", + "category": "School subjects", + "english": "geography", + "persian": "جغرافیا", + "finglish": "joghrâfiyâ" + }, + { + "id": "school_subjects_english", + "section": "Topic-specific vocabulary", + "category": "School subjects", + "english": "English", + "persian": "انگلیسی", + "finglish": "engelisi" + }, + { + "id": "school_subjects_persian", + "section": "Topic-specific vocabulary", + "category": "School subjects", + "english": "Persian", + "persian": "فارسی", + "finglish": "fârsi" + }, + { + "id": "school_subjects_art", + "section": "Topic-specific vocabulary", + "category": "School subjects", + "english": "art", + "persian": "هنر", + "finglish": "honar" + }, + { + "id": "school_subjects_music", + "section": "Topic-specific vocabulary", + "category": "School subjects", + "english": "music", + "persian": "موسیقی", + "finglish": "musighi" + }, + { + "id": "school_subjects_sport", + "section": "Topic-specific vocabulary", + "category": "School subjects", + "english": "sport", + "persian": "ورزش", + "finglish": "varzesh" + }, + { + "id": "school_subjects_physics", + "section": "Topic-specific vocabulary", + "category": "School subjects", + "english": "physics", + "persian": "فیزیک", + "finglish": "fizik" + }, + { + "id": "school_subjects_chemistry", + "section": "Topic-specific vocabulary", + "category": "School subjects", + "english": "chemistry", + "persian": "شیمی", + "finglish": "shimi" + }, + { + "id": "school_subjects_biology", + "section": "Topic-specific vocabulary", + "category": "School subjects", + "english": "biology", + "persian": "زیست‌شناسی", + "finglish": "zist-shenâsi" + }, + { + "id": "school_subjects_computer_science", + "section": "Topic-specific vocabulary", + "category": "School subjects", + "english": "computer science", + "persian": "علوم کامپیوتر", + "finglish": "olum-e kâmpyuter" + }, + { + "id": "school_subjects_religion", + "section": "Topic-specific vocabulary", + "category": "School subjects", + "english": "religion", + "persian": "دین", + "finglish": "din" + }, + { + "id": "school_life_student", + "section": "Topic-specific vocabulary", + "category": "School life", + "english": "student", + "persian": "دانش‌آموز", + "finglish": "dânesh-âmuz" + }, + { + "id": "school_life_teacher", + "section": "Topic-specific vocabulary", + "category": "School life", + "english": "teacher", + "persian": "معلم", + "finglish": "mo'allem" + }, + { + "id": "school_life_classroom", + "section": "Topic-specific vocabulary", + "category": "School life", + "english": "classroom", + "persian": "کلاس", + "finglish": "kelâs" + }, + { + "id": "school_life_lesson", + "section": "Topic-specific vocabulary", + "category": "School life", + "english": "lesson", + "persian": "درس", + "finglish": "dars" + }, + { + "id": "school_life_homework", + "section": "Topic-specific vocabulary", + "category": "School life", + "english": "homework", + "persian": "تکلیف", + "finglish": "taklif" + }, + { + "id": "school_life_exam", + "section": "Topic-specific vocabulary", + "category": "School life", + "english": "exam", + "persian": "امتحان", + "finglish": "emtehân" + }, + { + "id": "school_life_grade", + "section": "Topic-specific vocabulary", + "category": "School life", + "english": "grade", + "persian": "نمره", + "finglish": "nomre" + }, + { + "id": "school_life_book", + "section": "Topic-specific vocabulary", + "category": "School life", + "english": "book", + "persian": "کتاب", + "finglish": "ketâb" + }, + { + "id": "school_life_pen", + "section": "Topic-specific vocabulary", + "category": "School life", + "english": "pen", + "persian": "خودکار", + "finglish": "khodkâr" + }, + { + "id": "school_life_notebook", + "section": "Topic-specific vocabulary", + "category": "School life", + "english": "notebook", + "persian": "دفتر", + "finglish": "daftar" + }, + { + "id": "school_life_uniform", + "section": "Topic-specific vocabulary", + "category": "School life", + "english": "uniform", + "persian": "یونیفرم", + "finglish": "yuniform" + }, + { + "id": "school_life_break_time", + "section": "Topic-specific vocabulary", + "category": "School life", + "english": "break time", + "persian": "زنگ تفریح", + "finglish": "zang-e tafrih" + }, + { + "id": "school_life_headteacher", + "section": "Topic-specific vocabulary", + "category": "School life", + "english": "headteacher", + "persian": "مدیر مدرسه", + "finglish": "modir-e madrese" + }, + { + "id": "school_life_timetable", + "section": "Topic-specific vocabulary", + "category": "School life", + "english": "timetable", + "persian": "برنامه", + "finglish": "barnâme" + }, + { + "id": "jobs_and_careers_doctor", + "section": "Topic-specific vocabulary", + "category": "Jobs and careers", + "english": "doctor", + "persian": "دکتر", + "finglish": "doktar" + }, + { + "id": "jobs_and_careers_engineer", + "section": "Topic-specific vocabulary", + "category": "Jobs and careers", + "english": "engineer", + "persian": "مهندس", + "finglish": "mohandes" + }, + { + "id": "jobs_and_careers_teacher", + "section": "Topic-specific vocabulary", + "category": "Jobs and careers", + "english": "teacher", + "persian": "معلم", + "finglish": "mo'allem" + }, + { + "id": "jobs_and_careers_nurse", + "section": "Topic-specific vocabulary", + "category": "Jobs and careers", + "english": "nurse", + "persian": "پرستار", + "finglish": "parastâr" + }, + { + "id": "jobs_and_careers_lawyer", + "section": "Topic-specific vocabulary", + "category": "Jobs and careers", + "english": "lawyer", + "persian": "وکیل", + "finglish": "vakil" + }, + { + "id": "jobs_and_careers_driver", + "section": "Topic-specific vocabulary", + "category": "Jobs and careers", + "english": "driver", + "persian": "راننده", + "finglish": "rânande" + }, + { + "id": "jobs_and_careers_chef", + "section": "Topic-specific vocabulary", + "category": "Jobs and careers", + "english": "chef", + "persian": "آشپز", + "finglish": "âshpaz" + }, + { + "id": "jobs_and_careers_police_officer", + "section": "Topic-specific vocabulary", + "category": "Jobs and careers", + "english": "police officer", + "persian": "پلیس", + "finglish": "polis" + }, + { + "id": "jobs_and_careers_firefighter", + "section": "Topic-specific vocabulary", + "category": "Jobs and careers", + "english": "firefighter", + "persian": "آتش‌نشان", + "finglish": "âtash-neshân" + }, + { + "id": "jobs_and_careers_dentist", + "section": "Topic-specific vocabulary", + "category": "Jobs and careers", + "english": "dentist", + "persian": "دندانپزشک", + "finglish": "dandân-pezeshk" + }, + { + "id": "jobs_and_careers_journalist", + "section": "Topic-specific vocabulary", + "category": "Jobs and careers", + "english": "journalist", + "persian": "روزنامه‌نگار", + "finglish": "ruznâme-negâr" + }, + { + "id": "jobs_and_careers_businessman", + "section": "Topic-specific vocabulary", + "category": "Jobs and careers", + "english": "businessman", + "persian": "تاجر", + "finglish": "tâjer" + }, + { + "id": "jobs_and_careers_artist", + "section": "Topic-specific vocabulary", + "category": "Jobs and careers", + "english": "artist", + "persian": "هنرمند", + "finglish": "honarmand" + }, + { + "id": "jobs_and_careers_farmer", + "section": "Topic-specific vocabulary", + "category": "Jobs and careers", + "english": "farmer", + "persian": "کشاورز", + "finglish": "keshâvarz" + }, + { + "id": "jobs_and_careers_salary", + "section": "Topic-specific vocabulary", + "category": "Jobs and careers", + "english": "salary", + "persian": "حقوق", + "finglish": "hoghogh" + }, + { + "id": "future_plans_university", + "section": "Topic-specific vocabulary", + "category": "Future plans", + "english": "university", + "persian": "دانشگاه", + "finglish": "dâneshgâh" + }, + { + "id": "future_plans_to_study", + "section": "Topic-specific vocabulary", + "category": "Future plans", + "english": "to study", + "persian": "تحصیل کردن", + "finglish": "tahsil kardan" + }, + { + "id": "future_plans_career", + "section": "Topic-specific vocabulary", + "category": "Future plans", + "english": "career", + "persian": "شغل", + "finglish": "shoghl" + }, + { + "id": "future_plans_to_work", + "section": "Topic-specific vocabulary", + "category": "Future plans", + "english": "to work", + "persian": "کار کردن", + "finglish": "kâr kardan" + }, + { + "id": "future_plans_dream", + "section": "Topic-specific vocabulary", + "category": "Future plans", + "english": "dream", + "persian": "رویا", + "finglish": "royâ" + }, + { + "id": "future_plans_goal", + "section": "Topic-specific vocabulary", + "category": "Future plans", + "english": "goal", + "persian": "هدف", + "finglish": "hadaf" + }, + { + "id": "future_plans_success", + "section": "Topic-specific vocabulary", + "category": "Future plans", + "english": "success", + "persian": "موفقیت", + "finglish": "movaffaghiyat" + }, + { + "id": "future_plans_to_earn", + "section": "Topic-specific vocabulary", + "category": "Future plans", + "english": "to earn", + "persian": "درآمد داشتن", + "finglish": "darâmad dâshtan" + }, + { + "id": "future_plans_experience", + "section": "Topic-specific vocabulary", + "category": "Future plans", + "english": "experience", + "persian": "تجربه", + "finglish": "tajrobe" + }, + { + "id": "future_plans_opportunity", + "section": "Topic-specific vocabulary", + "category": "Future plans", + "english": "opportunity", + "persian": "فرصت", + "finglish": "forsat" + }, + { + "id": "transport_car", + "section": "Topic-specific vocabulary", + "category": "Transport", + "english": "car", + "persian": "ماشین", + "finglish": "mâshin" + }, + { + "id": "transport_bus", + "section": "Topic-specific vocabulary", + "category": "Transport", + "english": "bus", + "persian": "اتوبوس", + "finglish": "otobus" + }, + { + "id": "transport_train", + "section": "Topic-specific vocabulary", + "category": "Transport", + "english": "train", + "persian": "قطار", + "finglish": "ghatâr" + }, + { + "id": "transport_plane", + "section": "Topic-specific vocabulary", + "category": "Transport", + "english": "plane", + "persian": "هواپیما", + "finglish": "havâpeymâ" + }, + { + "id": "transport_taxi", + "section": "Topic-specific vocabulary", + "category": "Transport", + "english": "taxi", + "persian": "تاکسی", + "finglish": "tâksi" + }, + { + "id": "transport_bicycle", + "section": "Topic-specific vocabulary", + "category": "Transport", + "english": "bicycle", + "persian": "دوچرخه", + "finglish": "docharkhe" + }, + { + "id": "transport_motorcycle", + "section": "Topic-specific vocabulary", + "category": "Transport", + "english": "motorcycle", + "persian": "موتور", + "finglish": "motor" + }, + { + "id": "transport_ship", + "section": "Topic-specific vocabulary", + "category": "Transport", + "english": "ship", + "persian": "کشتی", + "finglish": "keshti" + }, + { + "id": "transport_metro", + "section": "Topic-specific vocabulary", + "category": "Transport", + "english": "metro", + "persian": "مترو", + "finglish": "metro" + }, + { + "id": "transport_airport", + "section": "Topic-specific vocabulary", + "category": "Transport", + "english": "airport", + "persian": "فرودگاه", + "finglish": "forudgâh" + }, + { + "id": "transport_station", + "section": "Topic-specific vocabulary", + "category": "Transport", + "english": "station", + "persian": "ایستگاه", + "finglish": "istgâh" + }, + { + "id": "transport_ticket", + "section": "Topic-specific vocabulary", + "category": "Transport", + "english": "ticket", + "persian": "بلیط", + "finglish": "belit" + }, + { + "id": "transport_passport", + "section": "Topic-specific vocabulary", + "category": "Transport", + "english": "passport", + "persian": "گذرنامه", + "finglish": "gozarnâme" + }, + { + "id": "directions_right", + "section": "Topic-specific vocabulary", + "category": "Directions", + "english": "right", + "persian": "راست", + "finglish": "râst" + }, + { + "id": "directions_left", + "section": "Topic-specific vocabulary", + "category": "Directions", + "english": "left", + "persian": "چپ", + "finglish": "chap" + }, + { + "id": "directions_straight", + "section": "Topic-specific vocabulary", + "category": "Directions", + "english": "straight", + "persian": "مستقیم", + "finglish": "mostaghim" + }, + { + "id": "directions_north", + "section": "Topic-specific vocabulary", + "category": "Directions", + "english": "north", + "persian": "شمال", + "finglish": "shomâl" + }, + { + "id": "directions_south", + "section": "Topic-specific vocabulary", + "category": "Directions", + "english": "south", + "persian": "جنوب", + "finglish": "jonub" + }, + { + "id": "directions_east", + "section": "Topic-specific vocabulary", + "category": "Directions", + "english": "east", + "persian": "شرق", + "finglish": "shargh" + }, + { + "id": "directions_west", + "section": "Topic-specific vocabulary", + "category": "Directions", + "english": "west", + "persian": "غرب", + "finglish": "gharb" + }, + { + "id": "directions_map", + "section": "Topic-specific vocabulary", + "category": "Directions", + "english": "map", + "persian": "نقشه", + "finglish": "naghshe" + }, + { + "id": "directions_turn", + "section": "Topic-specific vocabulary", + "category": "Directions", + "english": "turn", + "persian": "بپیچید", + "finglish": "bepichid" + }, + { + "id": "directions_next_to", + "section": "Topic-specific vocabulary", + "category": "Directions", + "english": "next to", + "persian": "کنار", + "finglish": "kenâr" + }, + { + "id": "directions_in_front_of", + "section": "Topic-specific vocabulary", + "category": "Directions", + "english": "in front of", + "persian": "جلوی", + "finglish": "jelo-ye" + }, + { + "id": "directions_far_from", + "section": "Topic-specific vocabulary", + "category": "Directions", + "english": "far from", + "persian": "دور از", + "finglish": "dur az" + }, + { + "id": "holiday_activities_to_travel", + "section": "Topic-specific vocabulary", + "category": "Holiday activities", + "english": "to travel", + "persian": "سفر کردن", + "finglish": "safar kardan" + }, + { + "id": "holiday_activities_to_visit", + "section": "Topic-specific vocabulary", + "category": "Holiday activities", + "english": "to visit", + "persian": "بازدید کردن", + "finglish": "bâzdid kardan" + }, + { + "id": "holiday_activities_to_swim", + "section": "Topic-specific vocabulary", + "category": "Holiday activities", + "english": "to swim", + "persian": "شنا کردن", + "finglish": "shenâ kardan" + }, + { + "id": "holiday_activities_to_take_photos", + "section": "Topic-specific vocabulary", + "category": "Holiday activities", + "english": "to take photos", + "persian": "عکس گرفتن", + "finglish": "aks gereftan" + }, + { + "id": "holiday_activities_to_relax", + "section": "Topic-specific vocabulary", + "category": "Holiday activities", + "english": "to relax", + "persian": "استراحت کردن", + "finglish": "esterâhat kardan" + }, + { + "id": "holiday_activities_sightseeing", + "section": "Topic-specific vocabulary", + "category": "Holiday activities", + "english": "sightseeing", + "persian": "گردشگری", + "finglish": "gardeshgari" + }, + { + "id": "holiday_activities_souvenir", + "section": "Topic-specific vocabulary", + "category": "Holiday activities", + "english": "souvenir", + "persian": "سوغاتی", + "finglish": "soghâti" + }, + { + "id": "holiday_activities_beach", + "section": "Topic-specific vocabulary", + "category": "Holiday activities", + "english": "beach", + "persian": "ساحل", + "finglish": "sâhel" + }, + { + "id": "holiday_activities_tourist", + "section": "Topic-specific vocabulary", + "category": "Holiday activities", + "english": "tourist", + "persian": "گردشگر", + "finglish": "gardeshgar" + }, + { + "id": "holiday_activities_luggage", + "section": "Topic-specific vocabulary", + "category": "Holiday activities", + "english": "luggage", + "persian": "چمدان", + "finglish": "chamedân" + }, + { + "id": "accommodation_hotel", + "section": "Topic-specific vocabulary", + "category": "Accommodation", + "english": "hotel", + "persian": "هتل", + "finglish": "hotel" + }, + { + "id": "accommodation_room", + "section": "Topic-specific vocabulary", + "category": "Accommodation", + "english": "room", + "persian": "اتاق", + "finglish": "otâgh" + }, + { + "id": "accommodation_reservation", + "section": "Topic-specific vocabulary", + "category": "Accommodation", + "english": "reservation", + "persian": "رزرو", + "finglish": "rezerv" + }, + { + "id": "accommodation_key", + "section": "Topic-specific vocabulary", + "category": "Accommodation", + "english": "key", + "persian": "کلید", + "finglish": "kelid" + }, + { + "id": "accommodation_reception", + "section": "Topic-specific vocabulary", + "category": "Accommodation", + "english": "reception", + "persian": "پذیرش", + "finglish": "paziresh" + }, + { + "id": "accommodation_single_room", + "section": "Topic-specific vocabulary", + "category": "Accommodation", + "english": "single room", + "persian": "اتاق یک‌نفره", + "finglish": "otâgh-e yek-nafare" + }, + { + "id": "accommodation_double_room", + "section": "Topic-specific vocabulary", + "category": "Accommodation", + "english": "double room", + "persian": "اتاق دونفره", + "finglish": "otâgh-e do-nafare" + }, + { + "id": "accommodation_breakfast_included", + "section": "Topic-specific vocabulary", + "category": "Accommodation", + "english": "breakfast included", + "persian": "صبحانه شامل", + "finglish": "sobhâne shâmel" + }, + { + "id": "accommodation_check_in", + "section": "Topic-specific vocabulary", + "category": "Accommodation", + "english": "check in", + "persian": "ورود", + "finglish": "vorud" + }, + { + "id": "accommodation_check_out", + "section": "Topic-specific vocabulary", + "category": "Accommodation", + "english": "check out", + "persian": "خروج", + "finglish": "khoruj" + }, + { + "id": "at_the_restaurant_menu", + "section": "Topic-specific vocabulary", + "category": "At the restaurant", + "english": "menu", + "persian": "منو", + "finglish": "menu" + }, + { + "id": "at_the_restaurant_waiter", + "section": "Topic-specific vocabulary", + "category": "At the restaurant", + "english": "waiter", + "persian": "گارسون", + "finglish": "gârsun" + }, + { + "id": "at_the_restaurant_bill", + "section": "Topic-specific vocabulary", + "category": "At the restaurant", + "english": "bill", + "persian": "صورتحساب", + "finglish": "surathesâb" + }, + { + "id": "at_the_restaurant_starter", + "section": "Topic-specific vocabulary", + "category": "At the restaurant", + "english": "starter", + "persian": "پیش‌غذا", + "finglish": "pish-ghazâ" + }, + { + "id": "at_the_restaurant_main_course", + "section": "Topic-specific vocabulary", + "category": "At the restaurant", + "english": "main course", + "persian": "غذای اصلی", + "finglish": "ghazâ-ye asli" + }, + { + "id": "at_the_restaurant_dessert", + "section": "Topic-specific vocabulary", + "category": "At the restaurant", + "english": "dessert", + "persian": "دسر", + "finglish": "deser" + }, + { + "id": "at_the_restaurant_drink", + "section": "Topic-specific vocabulary", + "category": "At the restaurant", + "english": "drink", + "persian": "نوشیدنی", + "finglish": "nushidani" + }, + { + "id": "at_the_restaurant_to_order", + "section": "Topic-specific vocabulary", + "category": "At the restaurant", + "english": "to order", + "persian": "سفارش دادن", + "finglish": "sefâresh dâdan" + }, + { + "id": "at_the_restaurant_delicious", + "section": "Topic-specific vocabulary", + "category": "At the restaurant", + "english": "delicious", + "persian": "خوشمزه", + "finglish": "khoshmaze" + }, + { + "id": "at_the_restaurant_vegetarian", + "section": "Topic-specific vocabulary", + "category": "At the restaurant", + "english": "vegetarian", + "persian": "گیاهخوار", + "finglish": "giyâh-khâr" + }, + { + "id": "at_the_restaurant_the_bill_please", + "section": "Topic-specific vocabulary", + "category": "At the restaurant", + "english": "the bill please", + "persian": "صورتحساب لطفا", + "finglish": "surathesâb lotfan" + }, + { + "id": "at_the_restaurant_tip", + "section": "Topic-specific vocabulary", + "category": "At the restaurant", + "english": "tip", + "persian": "انعام", + "finglish": "en'âm" + }, + { + "id": "health_health", + "section": "Topic-specific vocabulary", + "category": "Health", + "english": "health", + "persian": "سلامت", + "finglish": "salâmat" + }, + { + "id": "health_illness", + "section": "Topic-specific vocabulary", + "category": "Health", + "english": "illness", + "persian": "بیماری", + "finglish": "bimâri" + }, + { + "id": "health_headache", + "section": "Topic-specific vocabulary", + "category": "Health", + "english": "headache", + "persian": "سردرد", + "finglish": "sardard" + }, + { + "id": "health_stomach_ache", + "section": "Topic-specific vocabulary", + "category": "Health", + "english": "stomach ache", + "persian": "دل‌درد", + "finglish": "deldard" + }, + { + "id": "health_fever", + "section": "Topic-specific vocabulary", + "category": "Health", + "english": "fever", + "persian": "تب", + "finglish": "tab" + }, + { + "id": "health_cold_(illness)", + "section": "Topic-specific vocabulary", + "category": "Health", + "english": "cold (illness)", + "persian": "سرماخوردگی", + "finglish": "sarmâ-khordegi" + }, + { + "id": "health_medicine", + "section": "Topic-specific vocabulary", + "category": "Health", + "english": "medicine", + "persian": "دارو", + "finglish": "dâru" + }, + { + "id": "health_hospital", + "section": "Topic-specific vocabulary", + "category": "Health", + "english": "hospital", + "persian": "بیمارستان", + "finglish": "bimârestân" + }, + { + "id": "health_appointment", + "section": "Topic-specific vocabulary", + "category": "Health", + "english": "appointment", + "persian": "وقت ملاقات", + "finglish": "vaght-e molâghât" + }, + { + "id": "health_exercise", + "section": "Topic-specific vocabulary", + "category": "Health", + "english": "exercise", + "persian": "ورزش", + "finglish": "varzesh" + }, + { + "id": "health_healthy", + "section": "Topic-specific vocabulary", + "category": "Health", + "english": "healthy", + "persian": "سالم", + "finglish": "sâlem" + }, + { + "id": "health_pain", + "section": "Topic-specific vocabulary", + "category": "Health", + "english": "pain", + "persian": "درد", + "finglish": "dard" + }, + { + "id": "global_issues_poverty", + "section": "Topic-specific vocabulary", + "category": "Global issues", + "english": "poverty", + "persian": "فقر", + "finglish": "faghr" + }, + { + "id": "global_issues_war", + "section": "Topic-specific vocabulary", + "category": "Global issues", + "english": "war", + "persian": "جنگ", + "finglish": "jang" + }, + { + "id": "global_issues_peace", + "section": "Topic-specific vocabulary", + "category": "Global issues", + "english": "peace", + "persian": "صلح", + "finglish": "solh" + }, + { + "id": "global_issues_equality", + "section": "Topic-specific vocabulary", + "category": "Global issues", + "english": "equality", + "persian": "برابری", + "finglish": "barâbari" + }, + { + "id": "global_issues_education", + "section": "Topic-specific vocabulary", + "category": "Global issues", + "english": "education", + "persian": "آموزش", + "finglish": "âmuzesh" + }, + { + "id": "global_issues_climate_change", + "section": "Topic-specific vocabulary", + "category": "Global issues", + "english": "climate change", + "persian": "تغییرات آب و هوایی", + "finglish": "taghyirât-e âb va havâyi" + }, + { + "id": "global_issues_pollution", + "section": "Topic-specific vocabulary", + "category": "Global issues", + "english": "pollution", + "persian": "آلودگی", + "finglish": "âludegi" + }, + { + "id": "global_issues_charity", + "section": "Topic-specific vocabulary", + "category": "Global issues", + "english": "charity", + "persian": "خیریه", + "finglish": "kheyriye" + }, + { + "id": "global_issues_rights", + "section": "Topic-specific vocabulary", + "category": "Global issues", + "english": "rights", + "persian": "حقوق", + "finglish": "hoghogh" + }, + { + "id": "global_issues_government", + "section": "Topic-specific vocabulary", + "category": "Global issues", + "english": "government", + "persian": "دولت", + "finglish": "dolat" + }, + { + "id": "technology_computer", + "section": "Topic-specific vocabulary", + "category": "Technology", + "english": "computer", + "persian": "کامپیوتر", + "finglish": "kâmpyuter" + }, + { + "id": "technology_phone", + "section": "Topic-specific vocabulary", + "category": "Technology", + "english": "phone", + "persian": "تلفن", + "finglish": "telefon" + }, + { + "id": "technology_mobile_phone", + "section": "Topic-specific vocabulary", + "category": "Technology", + "english": "mobile phone", + "persian": "موبایل", + "finglish": "mobâyl" + }, + { + "id": "technology_internet", + "section": "Topic-specific vocabulary", + "category": "Technology", + "english": "internet", + "persian": "اینترنت", + "finglish": "internet" + }, + { + "id": "technology_website", + "section": "Topic-specific vocabulary", + "category": "Technology", + "english": "website", + "persian": "وبسایت", + "finglish": "vebsâyt" + }, + { + "id": "technology_email", + "section": "Topic-specific vocabulary", + "category": "Technology", + "english": "email", + "persian": "ایمیل", + "finglish": "imeyl" + }, + { + "id": "technology_screen", + "section": "Topic-specific vocabulary", + "category": "Technology", + "english": "screen", + "persian": "صفحه نمایش", + "finglish": "safhe-ye namâyesh" + }, + { + "id": "technology_to_download", + "section": "Topic-specific vocabulary", + "category": "Technology", + "english": "to download", + "persian": "دانلود کردن", + "finglish": "dânlod kardan" + }, + { + "id": "technology_to_search", + "section": "Topic-specific vocabulary", + "category": "Technology", + "english": "to search", + "persian": "جستجو کردن", + "finglish": "jostoju kardan" + }, + { + "id": "technology_keyboard", + "section": "Topic-specific vocabulary", + "category": "Technology", + "english": "keyboard", + "persian": "صفحه کلید", + "finglish": "safhe-ye kelid" + }, + { + "id": "technology_password", + "section": "Topic-specific vocabulary", + "category": "Technology", + "english": "password", + "persian": "رمز عبور", + "finglish": "ramz-e obur" + }, + { + "id": "technology_application", + "section": "Topic-specific vocabulary", + "category": "Technology", + "english": "application", + "persian": "برنامه", + "finglish": "barnâme" + }, + { + "id": "social_media_social_media", + "section": "Topic-specific vocabulary", + "category": "Social media", + "english": "social media", + "persian": "شبکه‌های اجتماعی", + "finglish": "shabake-hâ-ye ejtemâ'i" + }, + { + "id": "social_media_to_share", + "section": "Topic-specific vocabulary", + "category": "Social media", + "english": "to share", + "persian": "به اشتراک گذاشتن", + "finglish": "be eshterâk gozâshtan" + }, + { + "id": "social_media_to_follow", + "section": "Topic-specific vocabulary", + "category": "Social media", + "english": "to follow", + "persian": "دنبال کردن", + "finglish": "donbâl kardan" + }, + { + "id": "social_media_to_like", + "section": "Topic-specific vocabulary", + "category": "Social media", + "english": "to like", + "persian": "لایک کردن", + "finglish": "lâyk kardan" + }, + { + "id": "social_media_message", + "section": "Topic-specific vocabulary", + "category": "Social media", + "english": "message", + "persian": "پیام", + "finglish": "payâm" + }, + { + "id": "social_media_photo", + "section": "Topic-specific vocabulary", + "category": "Social media", + "english": "photo", + "persian": "عکس", + "finglish": "aks" + }, + { + "id": "social_media_video", + "section": "Topic-specific vocabulary", + "category": "Social media", + "english": "video", + "persian": "ویدیو", + "finglish": "vidiyo" + }, + { + "id": "social_media_online", + "section": "Topic-specific vocabulary", + "category": "Social media", + "english": "online", + "persian": "آنلاین", + "finglish": "ânlâyn" + }, + { + "id": "social_media_profile", + "section": "Topic-specific vocabulary", + "category": "Social media", + "english": "profile", + "persian": "پروفایل", + "finglish": "profâyl" + }, + { + "id": "social_media_to_post", + "section": "Topic-specific vocabulary", + "category": "Social media", + "english": "to post", + "persian": "پست کردن", + "finglish": "post kardan" + } +] \ No newline at end of file diff --git a/python/persian-tutor/db.py b/python/persian-tutor/db.py new file mode 100644 index 0000000..0ec5823 --- /dev/null +++ b/python/persian-tutor/db.py @@ -0,0 +1,234 @@ +"""SQLite database layer with FSRS spaced repetition integration.""" + +import json +import sqlite3 +from datetime import datetime, timezone +from pathlib import Path + +import fsrs + +DB_PATH = Path(__file__).parent / "data" / "progress.db" + +_conn = None +_scheduler = fsrs.Scheduler() + + +def get_connection(): + """Return the shared SQLite connection (singleton).""" + global _conn + if _conn is None: + DB_PATH.parent.mkdir(parents=True, exist_ok=True) + _conn = sqlite3.connect(str(DB_PATH), check_same_thread=False) + _conn.row_factory = sqlite3.Row + _conn.execute("PRAGMA journal_mode=WAL") + return _conn + + +def init_db(): + """Create all tables if they don't exist. Called once at startup.""" + conn = get_connection() + conn.executescript(""" + CREATE TABLE IF NOT EXISTS word_progress ( + word_id TEXT PRIMARY KEY, + fsrs_state TEXT, + due TIMESTAMP, + stability REAL, + difficulty REAL, + reps INTEGER DEFAULT 0, + lapses INTEGER DEFAULT 0, + last_review TIMESTAMP + ); + + CREATE TABLE IF NOT EXISTS quiz_sessions ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + category TEXT, + total_questions INTEGER, + correct INTEGER, + duration_seconds INTEGER + ); + + CREATE TABLE IF NOT EXISTS essays ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + essay_text TEXT, + grade TEXT, + feedback TEXT, + theme TEXT + ); + + CREATE TABLE IF NOT EXISTS tutor_sessions ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + theme TEXT, + messages TEXT, + duration_seconds INTEGER + ); + """) + conn.commit() + + +def get_word_progress(word_id): + """Return learning state for one word, or None if never reviewed.""" + conn = get_connection() + row = conn.execute( + "SELECT * FROM word_progress WHERE word_id = ?", (word_id,) + ).fetchone() + return dict(row) if row else None + + +def update_word_progress(word_id, rating): + """Run FSRS algorithm, update due date/stability/difficulty. + + Args: + word_id: Vocabulary entry ID. + rating: fsrs.Rating value (Again=1, Hard=2, Good=3, Easy=4). + """ + conn = get_connection() + existing = get_word_progress(word_id) + + if existing and existing["fsrs_state"]: + card = fsrs.Card.from_dict(json.loads(existing["fsrs_state"])) + else: + card = fsrs.Card() + + card, review_log = _scheduler.review_card(card, rating) + + now = datetime.now(timezone.utc).isoformat() + card_json = json.dumps(card.to_dict(), default=str) + + conn.execute( + """INSERT OR REPLACE INTO word_progress + (word_id, fsrs_state, due, stability, difficulty, reps, lapses, last_review) + VALUES (?, ?, ?, ?, ?, ?, ?, ?)""", + ( + word_id, + card_json, + card.due.isoformat(), + card.stability, + card.difficulty, + (existing["reps"] + 1) if existing else 1, + existing["lapses"] if existing else 0, + now, + ), + ) + conn.commit() + return card + + +def get_due_words(limit=20): + """Return word IDs where due <= now, ordered by due date.""" + conn = get_connection() + now = datetime.now(timezone.utc).isoformat() + rows = conn.execute( + "SELECT word_id FROM word_progress WHERE due <= ? ORDER BY due LIMIT ?", + (now, limit), + ).fetchall() + return [row["word_id"] for row in rows] + + +def get_word_counts(total_vocab_size=0): + """Return dict with total/seen/mastered/due counts for dashboard.""" + conn = get_connection() + now = datetime.now(timezone.utc).isoformat() + + seen = conn.execute("SELECT COUNT(*) FROM word_progress").fetchone()[0] + mastered = conn.execute( + "SELECT COUNT(*) FROM word_progress WHERE stability > 10" + ).fetchone()[0] + due = conn.execute( + "SELECT COUNT(*) FROM word_progress WHERE due <= ?", (now,) + ).fetchone()[0] + + return { + "total": total_vocab_size, + "seen": seen, + "mastered": mastered, + "due": due, + } + + +def record_quiz_session(category, total_questions, correct, duration_seconds): + """Log a completed flashcard session.""" + conn = get_connection() + conn.execute( + "INSERT INTO quiz_sessions (category, total_questions, correct, duration_seconds) VALUES (?, ?, ?, ?)", + (category, total_questions, correct, duration_seconds), + ) + conn.commit() + + +def save_essay(essay_text, grade, feedback, theme): + """Save an essay + AI feedback.""" + conn = get_connection() + conn.execute( + "INSERT INTO essays (essay_text, grade, feedback, theme) VALUES (?, ?, ?, ?)", + (essay_text, grade, feedback, theme), + ) + conn.commit() + + +def save_tutor_session(theme, messages, duration_seconds): + """Save a tutor conversation.""" + conn = get_connection() + conn.execute( + "INSERT INTO tutor_sessions (theme, messages, duration_seconds) VALUES (?, ?, ?)", + (theme, json.dumps(messages, ensure_ascii=False), duration_seconds), + ) + conn.commit() + + +def get_stats(): + """Aggregate data for the dashboard.""" + conn = get_connection() + + recent_quizzes = conn.execute( + "SELECT * FROM quiz_sessions ORDER BY timestamp DESC LIMIT 10" + ).fetchall() + + total_reviews = conn.execute( + "SELECT COALESCE(SUM(reps), 0) FROM word_progress" + ).fetchone()[0] + + total_quizzes = conn.execute( + "SELECT COUNT(*) FROM quiz_sessions" + ).fetchone()[0] + + # Streak: count consecutive days with activity + days = conn.execute( + "SELECT DISTINCT DATE(last_review) as d FROM word_progress WHERE last_review IS NOT NULL ORDER BY d DESC" + ).fetchall() + + streak = 0 + today = datetime.now(timezone.utc).date() + for i, row in enumerate(days): + day = datetime.fromisoformat(row["d"]).date() if isinstance(row["d"], str) else row["d"] + expected = today - __import__("datetime").timedelta(days=i) + if day == expected: + streak += 1 + else: + break + + return { + "recent_quizzes": [dict(r) for r in recent_quizzes], + "total_reviews": total_reviews, + "total_quizzes": total_quizzes, + "streak": streak, + } + + +def get_recent_essays(limit=10): + """Return recent essays for the essay history view.""" + conn = get_connection() + rows = conn.execute( + "SELECT * FROM essays ORDER BY timestamp DESC LIMIT ?", (limit,) + ).fetchall() + return [dict(r) for r in rows] + + +def close(): + """Close the database connection.""" + global _conn + if _conn: + _conn.close() + _conn = None diff --git a/python/persian-tutor/modules/__init__.py b/python/persian-tutor/modules/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/python/persian-tutor/modules/dashboard.py b/python/persian-tutor/modules/dashboard.py new file mode 100644 index 0000000..05e3c5f --- /dev/null +++ b/python/persian-tutor/modules/dashboard.py @@ -0,0 +1,84 @@ +"""Dashboard: progress stats, charts, and overview.""" + +import db +from modules.vocab import load_vocab, get_categories + + +def get_overview(): + """Return overview stats: total words, seen, mastered, due today.""" + vocab = load_vocab() + counts = db.get_word_counts(total_vocab_size=len(vocab)) + stats = db.get_stats() + counts["streak"] = stats["streak"] + counts["total_reviews"] = stats["total_reviews"] + counts["total_quizzes"] = stats["total_quizzes"] + return counts + + +def get_category_breakdown(): + """Return progress per category as list of dicts.""" + vocab = load_vocab() + categories = get_categories() + + breakdown = [] + for cat in categories: + cat_words = [e for e in vocab if e["category"] == cat] + cat_ids = {e["id"] for e in cat_words} + total = len(cat_words) + + seen = 0 + mastered = 0 + for wid in cat_ids: + progress = db.get_word_progress(wid) + if progress: + seen += 1 + if progress["stability"] and progress["stability"] > 10: + mastered += 1 + + breakdown.append({ + "Category": cat, + "Total": total, + "Seen": seen, + "Mastered": mastered, + "Progress": f"{seen}/{total}" if total > 0 else "0/0", + }) + + return breakdown + + +def get_recent_quizzes(limit=10): + """Return recent quiz results as list of dicts for display.""" + stats = db.get_stats() + quizzes = stats["recent_quizzes"][:limit] + result = [] + for q in quizzes: + result.append({ + "Date": q["timestamp"], + "Category": q["category"] or "All", + "Score": f"{q['correct']}/{q['total_questions']}", + "Duration": f"{q['duration_seconds'] or 0}s", + }) + return result + + +def format_overview_markdown(): + """Format overview stats as a markdown string for display.""" + o = get_overview() + pct = (o["seen"] / o["total"] * 100) if o["total"] > 0 else 0 + bar_filled = int(pct / 5) + bar_empty = 20 - bar_filled + progress_bar = "█" * bar_filled + "░" * bar_empty + + lines = [ + "## Dashboard", + "", + f"**Words studied:** {o['seen']} / {o['total']} ({pct:.0f}%)", + f"`{progress_bar}`", + "", + f"**Due today:** {o['due']}", + f"**Mastered:** {o['mastered']}", + f"**Daily streak:** {o['streak']} day{'s' if o['streak'] != 1 else ''}", + f"**Total reviews:** {o['total_reviews']}", + f"**Quiz sessions:** {o['total_quizzes']}", + ] + return "\n".join(lines) diff --git a/python/persian-tutor/modules/essay.py b/python/persian-tutor/modules/essay.py new file mode 100644 index 0000000..eb18ddb --- /dev/null +++ b/python/persian-tutor/modules/essay.py @@ -0,0 +1,78 @@ +"""Essay writing and AI marking.""" + +import db +from ai import ask + +MARKING_SYSTEM_PROMPT = """You are an expert Persian (Farsi) language teacher marking a GCSE-level essay. +You write in English but can read and correct Persian text. +Always provide constructive, encouraging feedback suitable for a language learner.""" + +MARKING_PROMPT_TEMPLATE = """Please mark this Persian essay written by a GCSE student. + +Theme: {theme} + +Student's essay: +{essay_text} + +Please provide your response in this exact format: + +**Grade:** [Give a grade from 1-9 matching GCSE grading, or a descriptive level like A2/B1] + +**Summary:** [1-2 sentence overview of the essay quality] + +**Corrections:** +[List specific errors with corrections. For each error, show the original text and the corrected version in Persian, with an English explanation] + +**Improved version:** +[Rewrite the essay in corrected Persian] + +**Tips for improvement:** +[3-5 specific, actionable tips for the student]""" + + +GCSE_THEMES = [ + "Identity and culture", + "Local area and environment", + "School and work", + "Travel and tourism", + "International and global dimension", +] + + +def mark_essay(essay_text, theme="General"): + """Send essay to AI for marking. Returns structured feedback.""" + if not essay_text or not essay_text.strip(): + return "Please write an essay first." + + prompt = MARKING_PROMPT_TEMPLATE.format( + theme=theme, + essay_text=essay_text.strip(), + ) + + feedback = ask(prompt, system=MARKING_SYSTEM_PROMPT, quality="smart") + + # Extract grade from feedback (best-effort) + grade = "" + for line in feedback.split("\n"): + if line.strip().startswith("**Grade:**"): + grade = line.replace("**Grade:**", "").strip() + break + + # Save to database + db.save_essay(essay_text.strip(), grade, feedback, theme) + + return feedback + + +def get_essay_history(limit=10): + """Return recent essays for the history view.""" + essays = db.get_recent_essays(limit) + result = [] + for e in essays: + result.append({ + "Date": e["timestamp"], + "Theme": e["theme"] or "General", + "Grade": e["grade"] or "-", + "Preview": (e["essay_text"] or "")[:50] + "...", + }) + return result diff --git a/python/persian-tutor/modules/idioms.py b/python/persian-tutor/modules/idioms.py new file mode 100644 index 0000000..1a5e2cf --- /dev/null +++ b/python/persian-tutor/modules/idioms.py @@ -0,0 +1,200 @@ +"""Persian idioms, expressions, and social conventions.""" + +from ai import ask + +# Built-in collection of common Persian expressions and idioms +EXPRESSIONS = [ + { + "persian": "سلام علیکم", + "finglish": "salâm aleykom", + "english": "Peace be upon you (formal greeting)", + "context": "Formal greeting, especially with elders", + }, + { + "persian": "خسته نباشید", + "finglish": "khaste nabâshid", + "english": "May you not be tired", + "context": "Common greeting to someone who has been working. Used as 'hello' in shops, offices, etc.", + }, + { + "persian": "دستت درد نکنه", + "finglish": "dastet dard nakone", + "english": "May your hand not hurt", + "context": "Thank you for your effort (after someone does something for you)", + }, + { + "persian": "قابلی نداره", + "finglish": "ghâbeli nadâre", + "english": "It's not worthy (of you)", + "context": "You're welcome / Don't mention it — said when giving a gift or doing a favour", + }, + { + "persian": "تعارف نکن", + "finglish": "ta'ârof nakon", + "english": "Don't do ta'arof", + "context": "Stop being politely modest — please accept! Part of Persian ta'arof culture.", + }, + { + "persian": "نوش جان", + "finglish": "nush-e jân", + "english": "May it nourish your soul", + "context": "Said to someone eating — like 'bon appétit' or 'enjoy your meal'", + }, + { + "persian": "چشمت روز بد نبینه", + "finglish": "cheshmet ruz-e bad nabine", + "english": "May your eyes never see a bad day", + "context": "A warm wish for someone's wellbeing", + }, + { + "persian": "قدمت روی چشم", + "finglish": "ghadamet ru-ye cheshm", + "english": "Your step is on my eye", + "context": "Warm welcome — 'you're very welcome here'. Extremely hospitable expression.", + }, + { + "persian": "ان‌شاءالله", + "finglish": "inshâ'allâh", + "english": "God willing", + "context": "Used when talking about future plans. Very common in daily speech.", + }, + { + "persian": "ماشاءالله", + "finglish": "mâshâ'allâh", + "english": "What God has willed", + "context": "Expression of admiration or praise, also used to ward off the evil eye.", + }, + { + "persian": "الهی شکر", + "finglish": "elâhi shokr", + "english": "Thank God", + "context": "Expression of gratitude, similar to 'thankfully'", + }, + { + "persian": "به سلامتی", + "finglish": "be salâmati", + "english": "To your health / Cheers", + "context": "A toast or general well-wishing expression", + }, + { + "persian": "عید مبارک", + "finglish": "eyd mobârak", + "english": "Happy holiday/celebration", + "context": "Used for any celebration, especially Nowruz", + }, + { + "persian": "تسلیت می‌گم", + "finglish": "tasliyat migam", + "english": "I offer my condolences", + "context": "Expressing sympathy when someone has lost a loved one", + }, + { + "persian": "خدا بیامرزه", + "finglish": "khodâ biâmorzesh", + "english": "May God forgive them (rest in peace)", + "context": "Said about someone who has passed away", + }, + { + "persian": "زبونت رو گاز بگیر", + "finglish": "zaboonet ro gâz begir", + "english": "Bite your tongue", + "context": "Don't say such things! (similar to English 'touch wood')", + }, + { + "persian": "دمت گرم", + "finglish": "damet garm", + "english": "May your breath be warm", + "context": "Well done! / Good for you! (informal, friendly praise)", + }, + { + "persian": "چشم", + "finglish": "cheshm", + "english": "On my eye (I will do it)", + "context": "Respectful way of saying 'yes, I'll do it' — shows obedience/respect", + }, + { + "persian": "بفرمایید", + "finglish": "befarmâyid", + "english": "Please (go ahead / help yourself / come in)", + "context": "Very versatile polite expression: offering food, inviting someone in, or giving way", + }, + { + "persian": "ببخشید", + "finglish": "bebakhshid", + "english": "Excuse me / I'm sorry", + "context": "Used for both apologies and getting someone's attention", + }, + { + "persian": "مخلصیم", + "finglish": "mokhlesim", + "english": "I'm your humble servant", + "context": "Polite/humble way of saying goodbye or responding to a compliment (ta'arof)", + }, + { + "persian": "سرت سلامت باشه", + "finglish": "saret salâmat bâshe", + "english": "May your head be safe", + "context": "Expression of condolence — 'I'm sorry for your loss'", + }, + { + "persian": "روی ما رو زمین ننداز", + "finglish": "ru-ye mâ ro zamin nandâz", + "english": "Don't throw our face on the ground", + "context": "Please don't refuse/embarrass us — said when insisting on a request", + }, + { + "persian": "قربونت برم", + "finglish": "ghorboonet beram", + "english": "I'd sacrifice myself for you", + "context": "Term of endearment — very common among family and close friends", + }, + { + "persian": "جون دل", + "finglish": "jun-e del", + "english": "Life of my heart", + "context": "Affectionate term used with loved ones", + }, +] + + +def get_all_expressions(): + """Return all built-in expressions.""" + return EXPRESSIONS + + +def get_random_expression(): + """Pick a random expression.""" + import random + return random.choice(EXPRESSIONS) + + +def explain_expression(expression): + """Use AI to generate a detailed explanation with usage examples.""" + prompt = f"""Explain this Persian expression for an English-speaking student: + +Persian: {expression['persian']} +Transliteration: {expression['finglish']} +Literal meaning: {expression['english']} +Context: {expression['context']} + +Please provide: +1. A fuller explanation of when and how this is used +2. The cultural context (ta'arof, hospitality, etc.) +3. Two example dialogues showing it in use (in Persian with English translation) +4. Any variations or related expressions + +Keep it concise and student-friendly.""" + + return ask(prompt, quality="fast") + + +def format_expression(expr, show_transliteration="off"): + """Format an expression for display.""" + parts = [ + f'
{expr["persian"]}
', + f'
{expr["english"]}
', + ] + if show_transliteration != "off": + parts.append(f'
{expr["finglish"]}
') + parts.append(f'
{expr["context"]}
') + return "\n".join(parts) diff --git a/python/persian-tutor/modules/tutor.py b/python/persian-tutor/modules/tutor.py new file mode 100644 index 0000000..bea9012 --- /dev/null +++ b/python/persian-tutor/modules/tutor.py @@ -0,0 +1,65 @@ +"""Conversational Persian lessons by GCSE theme.""" + +import time + +import db +from ai import chat_ollama + +TUTOR_SYSTEM_PROMPT = """You are a friendly Persian (Farsi) language tutor teaching English-speaking GCSE students. + +Rules: +- Use a mix of English and Persian. Start mostly in English, gradually introducing more Persian. +- When you write Persian, also provide the Finglish transliteration in parentheses. +- Keep responses concise (2-4 sentences per turn). +- Ask the student to practice: translate phrases, answer questions in Persian, or fill in blanks. +- Correct mistakes gently and explain why. +- Stay on the current theme/topic. +- Use Iranian Persian (Farsi), not Dari or Tajik. +- Adapt to the student's level based on their responses.""" + +THEME_PROMPTS = { + "Identity and culture": "Let's practice talking about family, personality, daily routines, and Persian celebrations like Nowruz!", + "Local area and environment": "Let's practice talking about your home, neighbourhood, shopping, and the environment!", + "School and work": "Let's practice talking about school subjects, school life, jobs, and future plans!", + "Travel and tourism": "Let's practice talking about transport, directions, holidays, hotels, and restaurants!", + "International and global dimension": "Let's practice talking about health, global issues, technology, and social media!", + "Free conversation": "Let's have a free conversation in Persian! I'll help you along the way.", +} + + +def start_lesson(theme): + """Generate the opening message for a new lesson. + + Returns: + (assistant_message, messages_list) + """ + intro = THEME_PROMPTS.get(theme, THEME_PROMPTS["Free conversation"]) + system = TUTOR_SYSTEM_PROMPT + f"\n\nCurrent topic: {theme}. {intro}" + + messages = [{"role": "user", "content": f"I'd like to practice Persian. Today's theme is: {theme}"}] + response = chat_ollama(messages, system=system) + messages.append({"role": "assistant", "content": response}) + + return response, messages, system + + +def process_response(user_input, messages, system=None): + """Add user input to conversation, get AI response. + + Returns: + (assistant_response, updated_messages) + """ + if not user_input or not user_input.strip(): + return "", messages + + messages.append({"role": "user", "content": user_input.strip()}) + response = chat_ollama(messages, system=system) + messages.append({"role": "assistant", "content": response}) + + return response, messages + + +def save_session(theme, messages, start_time): + """Save the current tutor session to the database.""" + duration = int(time.time() - start_time) + db.save_tutor_session(theme, messages, duration) diff --git a/python/persian-tutor/modules/vocab.py b/python/persian-tutor/modules/vocab.py new file mode 100644 index 0000000..17262d5 --- /dev/null +++ b/python/persian-tutor/modules/vocab.py @@ -0,0 +1,152 @@ +"""Vocabulary search, flashcard logic, and FSRS-driven review.""" + +import json +import random +from pathlib import Path + +import fsrs + +import db + + +VOCAB_PATH = Path(__file__).parent.parent / "data" / "vocabulary.json" + +_vocab_data = None + + +def load_vocab(): + """Load vocabulary data from JSON (cached).""" + global _vocab_data + if _vocab_data is None: + with open(VOCAB_PATH, encoding="utf-8") as f: + _vocab_data = json.load(f) + return _vocab_data + + +def get_categories(): + """Return sorted list of unique categories.""" + vocab = load_vocab() + return sorted({entry["category"] for entry in vocab}) + + +def get_sections(): + """Return sorted list of unique sections.""" + vocab = load_vocab() + return sorted({entry["section"] for entry in vocab}) + + +def search(query, vocab_data=None): + """Search vocabulary by English or Persian text. Returns matching entries.""" + if not query or not query.strip(): + return [] + vocab = vocab_data or load_vocab() + query_lower = query.strip().lower() + results = [] + for entry in vocab: + if ( + query_lower in entry["english"].lower() + or query_lower in entry["persian"] + or (entry.get("finglish") and query_lower in entry["finglish"].lower()) + ): + results.append(entry) + return results + + +def get_random_word(vocab_data=None, category=None): + """Pick a random vocabulary entry, optionally filtered by category.""" + vocab = vocab_data or load_vocab() + if category and category != "All": + filtered = [e for e in vocab if e["category"] == category] + else: + filtered = vocab + if not filtered: + return None + return random.choice(filtered) + + +def get_flashcard_batch(count=10, category=None): + """Get a batch of words for flashcard study. + + Prioritizes due words (FSRS), then fills with new/random words. + """ + vocab = load_vocab() + + if category and category != "All": + pool = [e for e in vocab if e["category"] == category] + else: + pool = vocab + + # Get due words first + due_ids = db.get_due_words(limit=count) + due_entries = [e for e in pool if e["id"] in due_ids] + + # Fill remaining with unseen or random words + remaining = count - len(due_entries) + if remaining > 0: + seen_ids = {e["id"] for e in due_entries} + # Prefer unseen words + unseen = [e for e in pool if e["id"] not in seen_ids and not db.get_word_progress(e["id"])] + if len(unseen) >= remaining: + fill = random.sample(unseen, remaining) + else: + # Use all unseen + random from rest + fill = unseen + still_needed = remaining - len(fill) + rest = [e for e in pool if e["id"] not in seen_ids and e not in fill] + if rest: + fill.extend(random.sample(rest, min(still_needed, len(rest)))) + due_entries.extend(fill) + + random.shuffle(due_entries) + return due_entries + + +def check_answer(word_id, user_answer, direction="en_to_fa"): + """Check if user's answer matches the target word. + + Args: + word_id: Vocabulary entry ID. + user_answer: What the user typed. + direction: "en_to_fa" (user writes Persian) or "fa_to_en" (user writes English). + + Returns: + (is_correct, correct_answer, entry) + """ + vocab = load_vocab() + entry = next((e for e in vocab if e["id"] == word_id), None) + if not entry: + return False, "", None + + user_answer = user_answer.strip() + + if direction == "en_to_fa": + correct = entry["persian"].strip() + is_correct = user_answer == correct + else: + correct = entry["english"].strip().lower() + is_correct = user_answer.lower() == correct + + return is_correct, correct if not is_correct else user_answer, entry + + +def format_word_card(entry, show_transliteration="off"): + """Format a vocabulary entry for display as RTL-safe markdown.""" + parts = [] + parts.append(f'
{entry["persian"]}
') + parts.append(f'
{entry["english"]}
') + + if show_transliteration != "off" and entry.get("finglish"): + parts.append(f'
{entry["finglish"]}
') + + parts.append(f'
{entry.get("category", "")}
') + return "\n".join(parts) + + +def get_word_status(word_id): + """Return status string for a word: new, learning, or mastered.""" + progress = db.get_word_progress(word_id) + if not progress: + return "new" + if progress["stability"] and progress["stability"] > 10: + return "mastered" + return "learning" diff --git a/python/persian-tutor/requirements.txt b/python/persian-tutor/requirements.txt new file mode 100644 index 0000000..7d6724b --- /dev/null +++ b/python/persian-tutor/requirements.txt @@ -0,0 +1,3 @@ +gradio>=4.0 +genanki +fsrs diff --git a/python/persian-tutor/scripts/build_vocab.py b/python/persian-tutor/scripts/build_vocab.py new file mode 100644 index 0000000..a24508b --- /dev/null +++ b/python/persian-tutor/scripts/build_vocab.py @@ -0,0 +1,1100 @@ +#!/usr/bin/env python3 +"""Build vocabulary.json from inline data.""" +import json +from pathlib import Path + +vocab = [] + +def add(section, category, entries): + for eng, per, fin in entries: + wid = category.lower().replace(" ", "_").replace("/", "_").replace("&", "and") + word = eng.lower().replace(" ", "_").replace("to ", "").replace("'", "") + vocab.append({ + "id": f"{wid}_{word}", + "section": section, + "category": category, + "english": eng, + "persian": per, + "finglish": fin, + }) + +S1 = "High-frequency language" +S2 = "Topic-specific vocabulary" + +# ── Common verbs ── +add(S1, "Common verbs", [ + ("to accept", "قبول کردن", "ghabul kardan"), + ("to achieve", "بدست آوردن", "be dast âvardan"), + ("to add", "اضافه کردن", "ezâfe kardan"), + ("to agree", "موافقت کردن", "movâfeghat kardan"), + ("to allow", "اجازه دادن", "ejâze dâdan"), + ("to answer", "جواب دادن", "javâb dâdan"), + ("to arrive", "رسیدن", "residan"), + ("to ask", "پرسیدن", "porsidan"), + ("to be", "بودن", "budan"), + ("to become", "شدن", "shodan"), + ("to begin", "شروع کردن", "shoru' kardan"), + ("to believe", "باور کردن", "bâvar kardan"), + ("to bring", "آوردن", "âvardan"), + ("to build", "ساختن", "sâkhtan"), + ("to buy", "خریدن", "kharidan"), + ("to call", "زنگ زدن", "zang zadan"), + ("to carry", "حمل کردن", "haml kardan"), + ("to catch", "گرفتن", "gereftan"), + ("to change", "عوض کردن", "avaz kardan"), + ("to choose", "انتخاب کردن", "entekhâb kardan"), + ("to close", "بستن", "bastan"), + ("to come", "آمدن", "âmadan"), + ("to continue", "ادامه دادن", "edâme dâdan"), + ("to cook", "آشپزی کردن", "âshpazi kardan"), + ("to cost", "قیمت داشتن", "gheymat dâshtan"), + ("to count", "شمردن", "shemordan"), + ("to create", "ایجاد کردن", "ijâd kardan"), + ("to cross", "رد شدن", "rad shodan"), + ("to cry", "گریه کردن", "gerye kardan"), + ("to cut", "بریدن", "boridan"), + ("to dance", "رقصیدن", "raghsidan"), + ("to decide", "تصمیم گرفتن", "tasmim gereftan"), + ("to describe", "توصیف کردن", "tosif kardan"), + ("to develop", "توسعه دادن", "tose'e dâdan"), + ("to die", "مردن", "mordan"), + ("to do", "انجام دادن", "anjâm dâdan"), + ("to draw", "نقاشی کردن", "naghâshi kardan"), + ("to dream", "خواب دیدن", "khâb didan"), + ("to drink", "نوشیدن", "nushidan"), + ("to drive", "رانندگی کردن", "rânandegi kardan"), + ("to eat", "خوردن", "khordan"), + ("to enjoy", "لذت بردن", "lezzat bordan"), + ("to enter", "وارد شدن", "vâred shodan"), + ("to explain", "توضیح دادن", "tozih dâdan"), + ("to fall", "افتادن", "oftâdan"), + ("to feel", "احساس کردن", "ehsâs kardan"), + ("to find", "پیدا کردن", "peydâ kardan"), + ("to finish", "تمام کردن", "tamâm kardan"), + ("to fly", "پرواز کردن", "parvâz kardan"), + ("to follow", "دنبال کردن", "donbâl kardan"), + ("to forget", "فراموش کردن", "farâmush kardan"), + ("to get", "گرفتن", "gereftan"), + ("to give", "دادن", "dâdan"), + ("to go", "رفتن", "raftan"), + ("to grow", "رشد کردن", "roshd kardan"), + ("to happen", "اتفاق افتادن", "ettefâgh oftâdan"), + ("to hate", "متنفر بودن", "motenaffer budan"), + ("to have", "داشتن", "dâshtan"), + ("to hear", "شنیدن", "shenidan"), + ("to help", "کمک کردن", "komak kardan"), + ("to hold", "نگه داشتن", "negah dâshtan"), + ("to hope", "امیدوار بودن", "omidvâr budan"), + ("to hurt", "درد کردن", "dard kardan"), + ("to improve", "بهتر کردن", "behtar kardan"), + ("to include", "شامل شدن", "shâmel shodan"), + ("to invite", "دعوت کردن", "da'vat kardan"), + ("to join", "پیوستن", "peyvastan"), + ("to keep", "نگه داشتن", "negah dâshtan"), + ("to kill", "کشتن", "koshtan"), + ("to know", "دانستن", "dânestan"), + ("to laugh", "خندیدن", "khandidan"), + ("to learn", "یاد گرفتن", "yâd gereftan"), + ("to leave", "ترک کردن", "tark kardan"), + ("to let", "اجازه دادن", "ejâze dâdan"), + ("to like", "دوست داشتن", "dust dâshtan"), + ("to listen", "گوش دادن", "gush dâdan"), + ("to live", "زندگی کردن", "zendegi kardan"), + ("to look", "نگاه کردن", "negâh kardan"), + ("to lose", "از دست دادن", "az dast dâdan"), + ("to love", "عشق ورزیدن", "eshgh varzidan"), + ("to make", "درست کردن", "dorost kardan"), + ("to meet", "ملاقات کردن", "molâghât kardan"), + ("to miss", "دلتنگ بودن", "deltang budan"), + ("to move", "حرکت کردن", "harekat kardan"), + ("to need", "نیاز داشتن", "niyâz dâshtan"), + ("to open", "باز کردن", "bâz kardan"), + ("to pay", "پرداخت کردن", "pardâkht kardan"), + ("to play", "بازی کردن", "bâzi kardan"), + ("to practise", "تمرین کردن", "tamrin kardan"), + ("to prefer", "ترجیح دادن", "tarjih dâdan"), + ("to prepare", "آماده کردن", "âmâde kardan"), + ("to produce", "تولید کردن", "tolid kardan"), + ("to promise", "قول دادن", "ghol dâdan"), + ("to protect", "محافظت کردن", "mohâfezat kardan"), + ("to pull", "کشیدن", "keshidan"), + ("to push", "هل دادن", "hol dâdan"), + ("to put", "گذاشتن", "gozâshtan"), + ("to rain", "باران آمدن", "bârân âmadan"), + ("to read", "خواندن", "khândan"), + ("to receive", "دریافت کردن", "daryâft kardan"), + ("to remember", "به یاد آوردن", "be yâd âvardan"), + ("to repair", "تعمیر کردن", "ta'mir kardan"), + ("to repeat", "تکرار کردن", "tekrâr kardan"), + ("to rest", "استراحت کردن", "esterâhat kardan"), + ("to return", "برگشتن", "bargashtan"), + ("to run", "دویدن", "davidan"), + ("to save", "نجات دادن", "nejât dâdan"), + ("to say", "گفتن", "goftan"), + ("to see", "دیدن", "didan"), + ("to sell", "فروختن", "foroukhtan"), + ("to send", "فرستادن", "ferestâdan"), + ("to show", "نشان دادن", "neshân dâdan"), + ("to sing", "آواز خواندن", "âvâz khândan"), + ("to sit", "نشستن", "neshastan"), + ("to sleep", "خوابیدن", "khâbidan"), + ("to smell", "بو کردن", "bu kardan"), + ("to speak", "صحبت کردن", "sohbat kardan"), + ("to spend", "خرج کردن", "kharj kardan"), + ("to stand", "ایستادن", "istâdan"), + ("to start", "شروع کردن", "shoru' kardan"), + ("to stay", "ماندن", "mândan"), + ("to stop", "ایستادن", "istâdan"), + ("to study", "درس خواندن", "dars khândan"), + ("to succeed", "موفق شدن", "movaffagh shodan"), + ("to swim", "شنا کردن", "shenâ kardan"), + ("to take", "گرفتن", "gereftan"), + ("to talk", "حرف زدن", "harf zadan"), + ("to teach", "درس دادن", "dars dâdan"), + ("to tell", "گفتن", "goftan"), + ("to thank", "تشکر کردن", "tashakkor kardan"), + ("to think", "فکر کردن", "fekr kardan"), + ("to throw", "پرت کردن", "part kardan"), + ("to touch", "لمس کردن", "lams kardan"), + ("to travel", "سفر کردن", "safar kardan"), + ("to try", "سعی کردن", "sa'y kardan"), + ("to turn", "چرخیدن", "charkhidan"), + ("to understand", "فهمیدن", "fahmidan"), + ("to use", "استفاده کردن", "estefâde kardan"), + ("to visit", "دیدن کردن", "didan kardan"), + ("to wait", "صبر کردن", "sabr kardan"), + ("to wake", "بیدار شدن", "bidâr shodan"), + ("to walk", "راه رفتن", "râh raftan"), + ("to want", "خواستن", "khâstan"), + ("to wash", "شستن", "shostan"), + ("to watch", "تماشا کردن", "tamâshâ kardan"), + ("to wear", "پوشیدن", "pushidan"), + ("to win", "برنده شدن", "barande shodan"), + ("to work", "کار کردن", "kâr kardan"), + ("to worry", "نگران بودن", "negarân budan"), + ("to write", "نوشتن", "neveshtan"), +]) + +# ── Common adjectives ── +add(S1, "Common adjectives", [ + ("angry", "عصبانی", "asabâni"), + ("bad", "بد", "bad"), + ("beautiful", "زیبا", "zibâ"), + ("big", "بزرگ", "bozorg"), + ("boring", "خسته‌کننده", "khaste-konande"), + ("brave", "شجاع", "shojâ'"), + ("busy", "مشغول", "mashghul"), + ("calm", "آرام", "ârâm"), + ("cheap", "ارزان", "arzân"), + ("clean", "تمیز", "tamiz"), + ("clever", "باهوش", "bâhush"), + ("close", "نزدیک", "nazdik"), + ("cold", "سرد", "sard"), + ("comfortable", "راحت", "râhat"), + ("correct", "درست", "dorost"), + ("dangerous", "خطرناک", "khatarnâk"), + ("dark", "تاریک", "târik"), + ("dear", "عزیز", "aziz"), + ("deep", "عمیق", "amigh"), + ("delicious", "خوشمزه", "khoshmaze"), + ("difficult", "سخت", "sakht"), + ("dirty", "کثیف", "kasif"), + ("dry", "خشک", "khoshk"), + ("easy", "آسان", "âsân"), + ("empty", "خالی", "khâli"), + ("excellent", "عالی", "âli"), + ("exciting", "هیجان‌انگیز", "hayajân-angiz"), + ("expensive", "گران", "gerân"), + ("famous", "مشهور", "mashhur"), + ("far", "دور", "dur"), + ("fast", "سریع", "sari'"), + ("fat", "چاق", "châgh"), + ("favourite", "مورد علاقه", "mored-e alâghe"), + ("foreign", "خارجی", "khâreji"), + ("free", "آزاد", "âzâd"), + ("friendly", "مهربان", "mehrabân"), + ("full", "پر", "por"), + ("funny", "خنده‌دار", "khande-dâr"), + ("good", "خوب", "khub"), + ("great", "عالی", "âli"), + ("happy", "خوشحال", "khoshhâl"), + ("hard", "سخت", "sakht"), + ("healthy", "سالم", "sâlem"), + ("heavy", "سنگین", "sangin"), + ("high", "بلند", "boland"), + ("honest", "صادق", "sâdegh"), + ("horrible", "وحشتناک", "vahshatnâk"), + ("hot", "داغ", "dâgh"), + ("huge", "عظیم", "azim"), + ("hungry", "گرسنه", "gorosne"), + ("ill", "مریض", "mariz"), + ("important", "مهم", "mohem"), + ("impossible", "غیرممکن", "gheyr-e momken"), + ("interesting", "جالب", "jâleb"), + ("kind", "مهربان", "mehrabân"), + ("large", "بزرگ", "bozorg"), + ("last", "آخرین", "âkharin"), + ("late", "دیر", "dir"), + ("lazy", "تنبل", "tanbal"), + ("light", "سبک", "sabok"), + ("long", "بلند", "boland"), + ("loud", "بلند", "boland"), + ("low", "پایین", "pâyin"), + ("lucky", "خوش‌شانس", "khosh-shâns"), + ("modern", "مدرن", "modern"), + ("narrow", "باریک", "bârik"), + ("natural", "طبیعی", "tabi'i"), + ("near", "نزدیک", "nazdik"), + ("necessary", "لازم", "lâzem"), + ("new", "نو", "now"), + ("nice", "خوب", "khub"), + ("noisy", "پر سر و صدا", "por sar o sedâ"), + ("normal", "عادی", "âdi"), + ("old", "پیر", "pir"), + ("open", "باز", "bâz"), + ("painful", "دردناک", "dardnâk"), + ("perfect", "عالی", "âli"), + ("pleasant", "خوشایند", "khoshâyand"), + ("polite", "مودب", "mo'addab"), + ("poor", "فقیر", "faghir"), + ("popular", "محبوب", "mahbub"), + ("possible", "ممکن", "momken"), + ("pretty", "قشنگ", "ghashang"), + ("private", "خصوصی", "khosusi"), + ("proud", "مفتخر", "moftakher"), + ("quiet", "ساکت", "sâket"), + ("quick", "سریع", "sari'"), + ("ready", "آماده", "âmâde"), + ("real", "واقعی", "vâghe'i"), + ("rich", "پولدار", "puldâr"), + ("right", "درست", "dorost"), + ("rude", "بی‌ادب", "bi-adab"), + ("sad", "غمگین", "ghamgin"), + ("safe", "امن", "amn"), + ("serious", "جدی", "jeddi"), + ("short", "کوتاه", "kutâh"), + ("simple", "ساده", "sâde"), + ("slow", "آهسته", "âheste"), + ("small", "کوچک", "kuchak"), + ("smart", "باهوش", "bâhush"), + ("soft", "نرم", "narm"), + ("special", "خاص", "khâss"), + ("strange", "عجیب", "ajib"), + ("strict", "سختگیر", "sakhtgir"), + ("strong", "قوی", "ghavi"), + ("stupid", "احمق", "ahmagh"), + ("successful", "موفق", "movaffagh"), + ("sure", "مطمئن", "motma'en"), + ("surprised", "متعجب", "mota'ajjeb"), + ("sweet", "شیرین", "shirin"), + ("tall", "بلند قد", "boland-ghad"), + ("terrible", "وحشتناک", "vahshatnâk"), + ("thin", "لاغر", "lâghar"), + ("thirsty", "تشنه", "teshne"), + ("tired", "خسته", "khaste"), + ("traditional", "سنتی", "sonnati"), + ("true", "درست", "dorost"), + ("ugly", "زشت", "zesht"), + ("unfair", "ناعادلانه", "nâ-âdelâne"), + ("unhappy", "ناراحت", "nârâhat"), + ("useful", "مفید", "mofid"), + ("usual", "معمولی", "ma'muli"), + ("warm", "گرم", "garm"), + ("weak", "ضعیف", "za'if"), + ("well", "خوب", "khub"), + ("whole", "کامل", "kâmel"), + ("wide", "پهن", "pahn"), + ("wild", "وحشی", "vahshi"), + ("wonderful", "فوق‌العاده", "fogh-ol-âde"), + ("worried", "نگران", "negarân"), + ("wrong", "اشتباه", "eshtebâh"), + ("young", "جوان", "javân"), +]) + +# ── Common adverbs ── +add(S1, "Common adverbs", [ + ("a lot", "زیاد", "ziyâd"), + ("again", "دوباره", "dobâre"), + ("almost", "تقریبا", "taghribân"), + ("already", "قبلا", "ghablan"), + ("also", "همچنین", "hamchenin"), + ("always", "همیشه", "hamishe"), + ("badly", "بد", "bad"), + ("carefully", "با دقت", "bâ deghat"), + ("certainly", "حتما", "hatman"), + ("clearly", "واضح", "vâzeh"), + ("completely", "کاملا", "kâmelan"), + ("early", "زود", "zud"), + ("enough", "کافی", "kâfi"), + ("especially", "مخصوصا", "makhsusan"), + ("even", "حتی", "hattâ"), + ("exactly", "دقیقا", "daghighan"), + ("finally", "بالاخره", "belâkhare"), + ("fortunately", "خوشبختانه", "khoshbakhtâne"), + ("generally", "معمولا", "ma'mulan"), + ("hardly", "به سختی", "be sakhti"), + ("immediately", "فورا", "fowran"), + ("just", "فقط", "faghat"), + ("late", "دیر", "dir"), + ("loudly", "بلند", "boland"), + ("maybe", "شاید", "shâyad"), + ("never", "هرگز", "hargez"), + ("normally", "معمولا", "ma'mulan"), + ("often", "اغلب", "aghlab"), + ("only", "فقط", "faghat"), + ("perhaps", "شاید", "shâyad"), + ("please", "لطفا", "lotfan"), + ("quickly", "سریع", "sari'"), + ("quite", "نسبتا", "nesbatan"), + ("rarely", "به ندرت", "be nodrat"), + ("really", "واقعا", "vâghe'an"), + ("recently", "اخیرا", "akhiran"), + ("regularly", "مرتب", "morattab"), + ("slowly", "آهسته", "âheste"), + ("sometimes", "گاهی", "gâhi"), + ("soon", "زود", "zud"), + ("still", "هنوز", "hanuz"), + ("suddenly", "ناگهان", "nâgahân"), + ("then", "سپس", "sepas"), + ("together", "با هم", "bâ ham"), + ("too", "هم", "ham"), + ("unfortunately", "متاسفانه", "mota'assefâne"), + ("usually", "معمولا", "ma'mulan"), + ("very", "خیلی", "kheyli"), + ("well", "خوب", "khub"), +]) + +# ── Prepositions ── +add(S1, "Prepositions", [ + ("about", "درباره", "darbâre"), + ("above", "بالای", "bâlâ-ye"), + ("across", "آن طرف", "ân taraf"), + ("after", "بعد از", "ba'd az"), + ("against", "بر علیه", "bar aleyhe"), + ("along", "در امتداد", "dar emtedâd"), + ("among", "در میان", "dar miyân"), + ("around", "اطراف", "atrâf"), + ("at", "در", "dar"), + ("before", "قبل از", "ghabl az"), + ("behind", "پشت", "posht"), + ("below", "زیر", "zir"), + ("beside", "کنار", "kenâr"), + ("between", "بین", "beyn"), + ("by", "توسط", "tavasot"), + ("down", "پایین", "pâyin"), + ("during", "در طول", "dar tul"), + ("except", "به جز", "be joz"), + ("for", "برای", "barâye"), + ("from", "از", "az"), + ("in", "در", "dar"), + ("inside", "داخل", "dâkhel"), + ("into", "به داخل", "be dâkhel"), + ("near", "نزدیک", "nazdik"), + ("of", "از", "az"), + ("on", "روی", "ru-ye"), + ("opposite", "روبروی", "ruberu-ye"), + ("out", "بیرون", "birun"), + ("outside", "بیرون از", "birun az"), + ("over", "بالای", "bâlâ-ye"), + ("through", "از میان", "az miyân"), + ("to", "به", "be"), + ("towards", "به سوی", "be su-ye"), + ("under", "زیر", "zir"), + ("until", "تا", "tâ"), + ("up", "بالا", "bâlâ"), + ("with", "با", "bâ"), + ("without", "بدون", "bedun"), +]) + +# ── Colours ── +add(S1, "Colours", [ + ("black", "سیاه", "siyâh"), + ("blue", "آبی", "âbi"), + ("brown", "قهوه‌ای", "ghahve-i"), + ("gold", "طلایی", "talâyi"), + ("green", "سبز", "sabz"), + ("grey", "خاکستری", "khâkestari"), + ("orange", "نارنجی", "nârenji"), + ("pink", "صورتی", "surati"), + ("purple", "بنفش", "banafsh"), + ("red", "قرمز", "ghermez"), + ("silver", "نقره‌ای", "noghre-i"), + ("white", "سفید", "sefid"), + ("yellow", "زرد", "zard"), +]) + +# ── Numbers ── +add(S1, "Numbers", [ + ("zero", "صفر", "sefr"), + ("one", "یک", "yek"), + ("two", "دو", "do"), + ("three", "سه", "se"), + ("four", "چهار", "chahâr"), + ("five", "پنج", "panj"), + ("six", "شش", "shesh"), + ("seven", "هفت", "haft"), + ("eight", "هشت", "hasht"), + ("nine", "نه", "noh"), + ("ten", "ده", "dah"), + ("eleven", "یازده", "yâzdah"), + ("twelve", "دوازده", "davâzdah"), + ("thirteen", "سیزده", "sizdah"), + ("fourteen", "چهارده", "chahârdah"), + ("fifteen", "پانزده", "pânzdah"), + ("sixteen", "شانزده", "shânzdah"), + ("seventeen", "هفده", "hefdah"), + ("eighteen", "هجده", "hejdah"), + ("nineteen", "نوزده", "nuzdah"), + ("twenty", "بیست", "bist"), + ("thirty", "سی", "si"), + ("forty", "چهل", "chehel"), + ("fifty", "پنجاه", "panjâh"), + ("sixty", "شصت", "shast"), + ("seventy", "هفتاد", "haftâd"), + ("eighty", "هشتاد", "hashtâd"), + ("ninety", "نود", "navad"), + ("hundred", "صد", "sad"), + ("thousand", "هزار", "hezâr"), + ("million", "میلیون", "milyun"), + ("first", "اول", "avval"), + ("second", "دوم", "dovvom"), + ("third", "سوم", "sevvom"), + ("fourth", "چهارم", "chahârom"), + ("fifth", "پنجم", "panjom"), + ("last", "آخر", "âkhar"), +]) + +# ── Quantities ── +add(S1, "Quantities and measures", [ + ("all", "همه", "hame"), + ("another", "یکی دیگر", "yeki digar"), + ("both", "هر دو", "har do"), + ("each", "هر", "har"), + ("enough", "کافی", "kâfi"), + ("every", "هر", "har"), + ("few", "کم", "kam"), + ("half", "نصف", "nesf"), + ("less", "کمتر", "kamtar"), + ("little", "کمی", "kami"), + ("many", "زیاد", "ziyâd"), + ("more", "بیشتر", "bishtar"), + ("most", "بیشترین", "bishtarin"), + ("much", "زیاد", "ziyâd"), + ("none", "هیچ‌کدام", "hich-kodâm"), + ("other", "دیگر", "digar"), + ("several", "چندین", "chandin"), + ("some", "بعضی", "ba'zi"), + ("pair", "جفت", "joft"), + ("piece", "تکه", "tekke"), + ("part", "بخش", "bakhsh"), + ("kilo", "کیلو", "kilu"), + ("litre", "لیتر", "litr"), + ("metre", "متر", "metr"), +]) + +# ── Connecting words ── +add(S1, "Connecting words", [ + ("and", "و", "va"), + ("or", "یا", "yâ"), + ("but", "اما", "ammâ"), + ("because", "چون", "chon"), + ("so", "پس", "pas"), + ("if", "اگر", "agar"), + ("when", "وقتی", "vaghti"), + ("while", "در حالی که", "dar hâli ke"), + ("although", "اگرچه", "agarche"), + ("however", "با این حال", "bâ in hâl"), + ("therefore", "بنابراین", "banâbar-in"), + ("also", "همچنین", "hamchenin"), + ("then", "سپس", "sepas"), + ("that", "که", "ke"), + ("which", "که", "ke"), + ("who", "که", "ke"), + ("where", "جایی که", "jâyi ke"), + ("before", "قبل از اینکه", "ghabl az inke"), + ("after", "بعد از اینکه", "ba'd az inke"), + ("until", "تا اینکه", "tâ inke"), + ("since", "از وقتی که", "az vaghti ke"), + ("as", "همانطور که", "hamântour ke"), + ("unless", "مگر اینکه", "magar inke"), + ("moreover", "علاوه بر این", "alâve bar in"), + ("furthermore", "به علاوه", "be alâve"), +]) + +# ── Time expressions ── +add(S1, "Time expressions", [ + ("today", "امروز", "emruz"), + ("tomorrow", "فردا", "fardâ"), + ("yesterday", "دیروز", "diruz"), + ("now", "الان", "al'ân"), + ("then", "آن موقع", "ân moghe'"), + ("always", "همیشه", "hamishe"), + ("never", "هرگز", "hargez"), + ("sometimes", "گاهی اوقات", "gâhi oghât"), + ("often", "اغلب", "aghlab"), + ("already", "قبلا", "ghablan"), + ("soon", "به زودی", "be zudi"), + ("still", "هنوز", "hanuz"), + ("yet", "هنوز", "hanuz"), + ("ago", "پیش", "pish"), + ("later", "بعدا", "ba'dan"), + ("early", "زود", "zud"), + ("late", "دیر", "dir"), + ("morning", "صبح", "sobh"), + ("afternoon", "بعد از ظهر", "ba'd az zohr"), + ("evening", "عصر", "asr"), + ("night", "شب", "shab"), + ("midnight", "نیمه‌شب", "nime-shab"), + ("noon", "ظهر", "zohr"), + ("during", "در طول", "dar tul"), + ("since", "از", "az"), +]) + +# ── Days, months, seasons ── +add(S1, "Days and months", [ + ("Saturday", "شنبه", "shanbe"), + ("Sunday", "یکشنبه", "yekshanbe"), + ("Monday", "دوشنبه", "doshanbe"), + ("Tuesday", "سه‌شنبه", "seshanbe"), + ("Wednesday", "چهارشنبه", "chahârshanbe"), + ("Thursday", "پنجشنبه", "panjshanbe"), + ("Friday", "جمعه", "jom'e"), + ("Farvardin", "فروردین", "farvardin"), + ("Ordibehesht", "اردیبهشت", "ordibehesht"), + ("Khordad", "خرداد", "khordâd"), + ("Tir", "تیر", "tir"), + ("Mordad", "مرداد", "mordâd"), + ("Shahrivar", "شهریور", "shahrivar"), + ("Mehr", "مهر", "mehr"), + ("Aban", "آبان", "âbân"), + ("Azar", "آذر", "âzar"), + ("Dey", "دی", "dey"), + ("Bahman", "بهمن", "bahman"), + ("Esfand", "اسفند", "esfand"), + ("spring", "بهار", "bahâr"), + ("summer", "تابستان", "tâbestân"), + ("autumn", "پاییز", "pâyiz"), + ("winter", "زمستان", "zemestân"), +]) + +# ── Question words ── +add(S1, "Question words", [ + ("who", "کی", "ki"), + ("what", "چی", "chi"), + ("when", "کی", "key"), + ("where", "کجا", "kojâ"), + ("why", "چرا", "cherâ"), + ("how", "چطور", "chetor"), + ("which", "کدام", "kodâm"), + ("how much", "چقدر", "cheghadr"), + ("how many", "چند تا", "chand tâ"), + ("whose", "مال کی", "mâl-e ki"), + ("what kind of", "چه نوع", "che now'"), + ("how long", "چه مدت", "che moddat"), +]) + +# ── Useful expressions ── +add(S1, "Useful expressions", [ + ("hello", "سلام", "salâm"), + ("goodbye", "خداحافظ", "khodâhâfez"), + ("please", "لطفا", "lotfan"), + ("thank you", "ممنون", "mamnun"), + ("you're welcome", "خواهش می‌کنم", "khâhesh mikonam"), + ("excuse me", "ببخشید", "bebakhshid"), + ("sorry", "متاسفم", "mota'assefam"), + ("good morning", "صبح بخیر", "sobh bekheyr"), + ("good evening", "عصر بخیر", "asr bekheyr"), + ("good night", "شب بخیر", "shab bekheyr"), + ("how are you", "حالت چطوره", "hâlet chetore"), + ("I'm fine", "خوبم", "khubam"), + ("yes", "بله", "bale"), + ("no", "نه", "na"), + ("of course", "البته", "albatte"), + ("congratulations", "تبریک", "tabrik"), + ("happy birthday", "تولدت مبارک", "tavalodet mobârak"), + ("happy new year", "عید نوروز مبارک", "eyd-e nowruz mobârak"), + ("welcome", "خوش آمدید", "khosh âmadid"), + ("help", "کمک", "komak"), + ("I don't understand", "نمی‌فهمم", "nemifahmam"), + ("I don't know", "نمی‌دونم", "nemidounam"), + ("slowly please", "آهسته لطفا", "âheste lotfan"), + ("repeat please", "تکرار کنید لطفا", "tekrâr konid lotfan"), + ("what does this mean", "این یعنی چی", "in ya'ni chi"), + ("may I", "اجازه هست", "ejâze hast"), + ("it doesn't matter", "مهم نیست", "mohem nist"), + ("God willing", "ان‌شاءالله", "inshâ'allâh"), + ("bless you", "عافیت باشه", "âfiyat bâshe"), +]) + +# ── Countries ── +add(S1, "Countries", [ + ("Iran", "ایران", "irân"), + ("Afghanistan", "افغانستان", "afghânestân"), + ("Tajikistan", "تاجیکستان", "tâjikestân"), + ("Turkey", "ترکیه", "torkiye"), + ("Iraq", "عراق", "erâgh"), + ("England", "انگلستان", "engelestân"), + ("France", "فرانسه", "farânse"), + ("Germany", "آلمان", "âlmân"), + ("Spain", "اسپانیا", "espâniyâ"), + ("Italy", "ایتالیا", "itâliyâ"), + ("America", "آمریکا", "âmrikâ"), + ("Canada", "کانادا", "kânâdâ"), + ("Australia", "استرالیا", "ostrâliyâ"), + ("China", "چین", "chin"), + ("Japan", "ژاپن", "zhâpon"), + ("India", "هند", "hend"), + ("Russia", "روسیه", "rusiye"), + ("Pakistan", "پاکستان", "pâkestân"), + ("Saudi Arabia", "عربستان سعودی", "arabestân-e so'udi"), + ("Egypt", "مصر", "mesr"), + ("United Arab Emirates", "امارات متحده عربی", "emârât-e mottahed-e arabi"), + ("Syria", "سوریه", "suriye"), + ("Lebanon", "لبنان", "lobnân"), + ("Morocco", "مراکش", "marâkesh"), + ("Brazil", "برزیل", "berezil"), +]) + +# ── Nationalities ── +add(S1, "Nationalities", [ + ("Iranian", "ایرانی", "irâni"), + ("Afghan", "افغان", "afghân"), + ("English", "انگلیسی", "engelisi"), + ("French", "فرانسوی", "farânsavi"), + ("German", "آلمانی", "âlmâni"), + ("American", "آمریکایی", "âmrikâyi"), + ("Turkish", "ترک", "tork"), + ("Arab", "عرب", "arab"), + ("Indian", "هندی", "hendi"), + ("Chinese", "چینی", "chini"), + ("Japanese", "ژاپنی", "zhâponi"), + ("Russian", "روسی", "rusi"), + ("Italian", "ایتالیایی", "itâliyâyi"), + ("Spanish", "اسپانیایی", "espâniyâyi"), + ("Pakistani", "پاکستانی", "pâkestâni"), + ("Australian", "استرالیایی", "ostrâliyâyi"), + ("Canadian", "کانادایی", "kânâdâyi"), + ("Iraqi", "عراقی", "erâghi"), + ("Egyptian", "مصری", "mesri"), + ("Brazilian", "برزیلی", "berezili"), +]) + +# ── Social conventions ── +add(S1, "Social conventions", [ + ("greeting someone", "سلام و احوالپرسی", "salâm va ahvâlporsi"), + ("introducing yourself", "معرفی خود", "mo'arrefi-ye khod"), + ("asking about health", "احوالپرسی", "ahvâlporsi"), + ("thanking", "تشکر کردن", "tashakkor kardan"), + ("apologizing", "عذرخواهی کردن", "ozrkhâhi kardan"), + ("congratulating", "تبریک گفتن", "tabrik goftan"), + ("expressing condolence", "تسلیت گفتن", "tasliyat goftan"), + ("saying goodbye", "خداحافظی کردن", "khodâhâfezi kardan"), + ("welcoming guests", "خوشامدگویی", "khosh-âmad-guyi"), + ("offering food", "تعارف کردن غذا", "ta'ârof kardan-e ghazâ"), + ("accepting an offer", "قبول کردن", "ghabul kardan"), + ("declining an offer", "رد کردن", "rad kardan"), + ("asking permission", "اجازه خواستن", "ejâze khâstan"), + ("making a request", "درخواست کردن", "darkhâst kardan"), + ("showing respect", "احترام گذاشتن", "ehterâm gozâshtan"), +]) + +# ── Theme 1: Identity and culture ── +add(S2, "Family members", [ + ("father", "پدر", "pedar"), + ("mother", "مادر", "mâdar"), + ("brother", "برادر", "barâdar"), + ("sister", "خواهر", "khâhar"), + ("son", "پسر", "pesar"), + ("daughter", "دختر", "dokhtar"), + ("grandfather", "پدربزرگ", "pedar-bozorg"), + ("grandmother", "مادربزرگ", "mâdar-bozorg"), + ("uncle", "عمو / دایی", "amu / dâyi"), + ("aunt", "عمه / خاله", "amme / khâle"), + ("cousin", "پسرعمو / دخترعمو", "pesar-amu / dokhtar-amu"), + ("husband", "شوهر", "showhar"), + ("wife", "زن / همسر", "zan / hamsar"), + ("family", "خانواده", "khânevâde"), + ("child", "بچه", "bachche"), + ("baby", "نوزاد", "nowzâd"), +]) + +add(S2, "Physical descriptions", [ + ("hair", "مو", "mu"), + ("eye", "چشم", "cheshm"), + ("tall", "بلند قد", "boland-ghad"), + ("short (height)", "کوتاه قد", "kutâh-ghad"), + ("thin", "لاغر", "lâghar"), + ("fat", "چاق", "châgh"), + ("handsome", "خوش‌تیپ", "khosh-tip"), + ("curly hair", "موی فرفری", "mu-ye ferferi"), + ("straight hair", "موی صاف", "mu-ye sâf"), + ("beard", "ریش", "rish"), +]) + +add(S2, "Personality", [ + ("kind", "مهربان", "mehrabân"), + ("shy", "خجالتی", "khejâlati"), + ("generous", "سخاوتمند", "sakhâvatmand"), + ("patient", "صبور", "sabur"), + ("cheerful", "شاد", "shâd"), + ("hard-working", "زحمتکش", "zahmatkesh"), + ("honest", "صادق", "sâdegh"), + ("selfish", "خودخواه", "khod-khâh"), + ("reliable", "قابل اعتماد", "ghâbel-e e'temâd"), + ("stubborn", "لجباز", "lajbâz"), +]) + +add(S2, "Daily routine", [ + ("to wake up", "بیدار شدن", "bidâr shodan"), + ("to get dressed", "لباس پوشیدن", "lebâs pushidan"), + ("to have breakfast", "صبحانه خوردن", "sobhâne khordan"), + ("to go to school", "به مدرسه رفتن", "be madrese raftan"), + ("to have lunch", "ناهار خوردن", "nâhâr khordan"), + ("to do homework", "تکلیف انجام دادن", "taklif anjâm dâdan"), + ("to have dinner", "شام خوردن", "shâm khordan"), + ("to brush teeth", "مسواک زدن", "mesvâk zadan"), + ("to go to bed", "به رختخواب رفتن", "be rakhtekhâb raftan"), + ("to take a shower", "دوش گرفتن", "dush gereftan"), +]) + +add(S2, "Food and drink", [ + ("bread", "نان", "nân"), + ("rice", "برنج", "berenj"), + ("meat", "گوشت", "gusht"), + ("chicken", "مرغ", "morgh"), + ("fish", "ماهی", "mâhi"), + ("fruit", "میوه", "mive"), + ("vegetable", "سبزیجات", "sabzijât"), + ("water", "آب", "âb"), + ("tea", "چای", "châi"), + ("milk", "شیر", "shir"), + ("cheese", "پنیر", "panir"), + ("egg", "تخم‌مرغ", "tokhm-e morgh"), + ("sugar", "شکر", "shekar"), + ("salt", "نمک", "namak"), + ("kebab", "کباب", "kabâb"), + ("yogurt", "ماست", "mâst"), + ("soup", "سوپ", "sup"), + ("salad", "سالاد", "sâlâd"), + ("cake", "کیک", "keyk"), + ("ice cream", "بستنی", "bastani"), +]) + +add(S2, "Celebrations", [ + ("Nowruz", "نوروز", "nowruz"), + ("Haft-sin", "هفت‌سین", "haft-sin"), + ("Chaharshanbe Suri", "چهارشنبه‌سوری", "chahârshanbe-suri"), + ("Yalda night", "شب یلدا", "shab-e yaldâ"), + ("Sizdah Bedar", "سیزده‌بدر", "sizdah-bedar"), + ("celebration", "جشن", "jashn"), + ("gift", "هدیه", "hediye"), + ("holiday", "تعطیلات", "ta'tilât"), + ("tradition", "سنت", "sonnat"), + ("fireworks", "آتش‌بازی", "âtash-bâzi"), +]) + +# ── Theme 2: Local area and environment ── +add(S2, "House and home", [ + ("house", "خانه", "khâne"), + ("room", "اتاق", "otâgh"), + ("kitchen", "آشپزخانه", "âshpaz-khâne"), + ("bathroom", "حمام", "hammâm"), + ("bedroom", "اتاق خواب", "otâgh-e khâb"), + ("living room", "اتاق نشیمن", "otâgh-e neshiman"), + ("garden", "باغ", "bâgh"), + ("door", "در", "dar"), + ("window", "پنجره", "panjere"), + ("floor", "طبقه", "tabaghe"), + ("wall", "دیوار", "divâr"), + ("roof", "سقف", "saghf"), + ("stairs", "پله", "pelle"), + ("furniture", "مبل", "mobl"), + ("table", "میز", "miz"), + ("chair", "صندلی", "sandali"), +]) + +add(S2, "Places in town", [ + ("school", "مدرسه", "madrese"), + ("hospital", "بیمارستان", "bimârestân"), + ("mosque", "مسجد", "masjed"), + ("park", "پارک", "pârk"), + ("library", "کتابخانه", "ketâb-khâne"), + ("shop", "مغازه", "maghâze"), + ("market", "بازار", "bâzâr"), + ("bank", "بانک", "bânk"), + ("restaurant", "رستوران", "restorân"), + ("pharmacy", "داروخانه", "dâru-khâne"), + ("post office", "اداره پست", "edâre-ye post"), + ("cinema", "سینما", "sinamâ"), + ("museum", "موزه", "muze"), + ("street", "خیابان", "khiyâbân"), + ("square", "میدان", "meydân"), +]) + +add(S2, "Shopping", [ + ("to buy", "خریدن", "kharidan"), + ("to sell", "فروختن", "foroukhtan"), + ("price", "قیمت", "gheymat"), + ("money", "پول", "pul"), + ("cash", "نقد", "naghd"), + ("receipt", "رسید", "resid"), + ("discount", "تخفیف", "takhfif"), + ("size", "اندازه", "andâze"), + ("colour", "رنگ", "rang"), + ("bag", "کیف", "kif"), + ("clothes", "لباس", "lebâs"), + ("shoes", "کفش", "kafsh"), +]) + +add(S2, "Weather", [ + ("weather", "هوا", "havâ"), + ("sun", "خورشید", "khorshid"), + ("rain", "باران", "bârân"), + ("snow", "برف", "barf"), + ("wind", "باد", "bâd"), + ("cloud", "ابر", "abr"), + ("hot", "گرم", "garm"), + ("cold", "سرد", "sard"), + ("warm", "ملایم", "molâyem"), + ("sunny", "آفتابی", "âftâbi"), + ("cloudy", "ابری", "abri"), + ("rainy", "بارانی", "bârâni"), + ("temperature", "دما", "damâ"), + ("season", "فصل", "fasl"), +]) + +add(S2, "Environment", [ + ("nature", "طبیعت", "tabi'at"), + ("tree", "درخت", "derakht"), + ("flower", "گل", "gol"), + ("river", "رودخانه", "rudkhâne"), + ("mountain", "کوه", "kuh"), + ("sea", "دریا", "daryâ"), + ("forest", "جنگل", "jangal"), + ("desert", "بیابان", "biyâbân"), + ("animal", "حیوان", "heyvân"), + ("bird", "پرنده", "parande"), + ("pollution", "آلودگی", "âludegi"), + ("recycling", "بازیافت", "bâzyâft"), + ("environment", "محیط زیست", "mohit-e zist"), + ("earth", "زمین", "zamin"), +]) + +# ── Theme 3: School and work ── +add(S2, "School subjects", [ + ("mathematics", "ریاضی", "riyâzi"), + ("science", "علوم", "olum"), + ("history", "تاریخ", "târikh"), + ("geography", "جغرافیا", "joghrâfiyâ"), + ("English", "انگلیسی", "engelisi"), + ("Persian", "فارسی", "fârsi"), + ("art", "هنر", "honar"), + ("music", "موسیقی", "musighi"), + ("sport", "ورزش", "varzesh"), + ("physics", "فیزیک", "fizik"), + ("chemistry", "شیمی", "shimi"), + ("biology", "زیست‌شناسی", "zist-shenâsi"), + ("computer science", "علوم کامپیوتر", "olum-e kâmpyuter"), + ("religion", "دین", "din"), +]) + +add(S2, "School life", [ + ("student", "دانش‌آموز", "dânesh-âmuz"), + ("teacher", "معلم", "mo'allem"), + ("classroom", "کلاس", "kelâs"), + ("lesson", "درس", "dars"), + ("homework", "تکلیف", "taklif"), + ("exam", "امتحان", "emtehân"), + ("grade", "نمره", "nomre"), + ("book", "کتاب", "ketâb"), + ("pen", "خودکار", "khodkâr"), + ("notebook", "دفتر", "daftar"), + ("uniform", "یونیفرم", "yuniform"), + ("break time", "زنگ تفریح", "zang-e tafrih"), + ("headteacher", "مدیر مدرسه", "modir-e madrese"), + ("timetable", "برنامه", "barnâme"), +]) + +add(S2, "Jobs and careers", [ + ("doctor", "دکتر", "doktar"), + ("engineer", "مهندس", "mohandes"), + ("teacher", "معلم", "mo'allem"), + ("nurse", "پرستار", "parastâr"), + ("lawyer", "وکیل", "vakil"), + ("driver", "راننده", "rânande"), + ("chef", "آشپز", "âshpaz"), + ("police officer", "پلیس", "polis"), + ("firefighter", "آتش‌نشان", "âtash-neshân"), + ("dentist", "دندانپزشک", "dandân-pezeshk"), + ("journalist", "روزنامه‌نگار", "ruznâme-negâr"), + ("businessman", "تاجر", "tâjer"), + ("artist", "هنرمند", "honarmand"), + ("farmer", "کشاورز", "keshâvarz"), + ("salary", "حقوق", "hoghogh"), +]) + +add(S2, "Future plans", [ + ("university", "دانشگاه", "dâneshgâh"), + ("to study", "تحصیل کردن", "tahsil kardan"), + ("career", "شغل", "shoghl"), + ("to work", "کار کردن", "kâr kardan"), + ("dream", "رویا", "royâ"), + ("goal", "هدف", "hadaf"), + ("success", "موفقیت", "movaffaghiyat"), + ("to earn", "درآمد داشتن", "darâmad dâshtan"), + ("experience", "تجربه", "tajrobe"), + ("opportunity", "فرصت", "forsat"), +]) + +# ── Theme 4: Travel and tourism ── +add(S2, "Transport", [ + ("car", "ماشین", "mâshin"), + ("bus", "اتوبوس", "otobus"), + ("train", "قطار", "ghatâr"), + ("plane", "هواپیما", "havâpeymâ"), + ("taxi", "تاکسی", "tâksi"), + ("bicycle", "دوچرخه", "docharkhe"), + ("motorcycle", "موتور", "motor"), + ("ship", "کشتی", "keshti"), + ("metro", "مترو", "metro"), + ("airport", "فرودگاه", "forudgâh"), + ("station", "ایستگاه", "istgâh"), + ("ticket", "بلیط", "belit"), + ("passport", "گذرنامه", "gozarnâme"), +]) + +add(S2, "Directions", [ + ("right", "راست", "râst"), + ("left", "چپ", "chap"), + ("straight", "مستقیم", "mostaghim"), + ("north", "شمال", "shomâl"), + ("south", "جنوب", "jonub"), + ("east", "شرق", "shargh"), + ("west", "غرب", "gharb"), + ("map", "نقشه", "naghshe"), + ("turn", "بپیچید", "bepichid"), + ("next to", "کنار", "kenâr"), + ("in front of", "جلوی", "jelo-ye"), + ("far from", "دور از", "dur az"), +]) + +add(S2, "Holiday activities", [ + ("to travel", "سفر کردن", "safar kardan"), + ("to visit", "بازدید کردن", "bâzdid kardan"), + ("to swim", "شنا کردن", "shenâ kardan"), + ("to take photos", "عکس گرفتن", "aks gereftan"), + ("to relax", "استراحت کردن", "esterâhat kardan"), + ("sightseeing", "گردشگری", "gardeshgari"), + ("souvenir", "سوغاتی", "soghâti"), + ("beach", "ساحل", "sâhel"), + ("tourist", "گردشگر", "gardeshgar"), + ("luggage", "چمدان", "chamedân"), +]) + +add(S2, "Accommodation", [ + ("hotel", "هتل", "hotel"), + ("room", "اتاق", "otâgh"), + ("reservation", "رزرو", "rezerv"), + ("key", "کلید", "kelid"), + ("reception", "پذیرش", "paziresh"), + ("single room", "اتاق یک‌نفره", "otâgh-e yek-nafare"), + ("double room", "اتاق دونفره", "otâgh-e do-nafare"), + ("breakfast included", "صبحانه شامل", "sobhâne shâmel"), + ("check in", "ورود", "vorud"), + ("check out", "خروج", "khoruj"), +]) + +add(S2, "At the restaurant", [ + ("menu", "منو", "menu"), + ("waiter", "گارسون", "gârsun"), + ("bill", "صورتحساب", "surathesâb"), + ("starter", "پیش‌غذا", "pish-ghazâ"), + ("main course", "غذای اصلی", "ghazâ-ye asli"), + ("dessert", "دسر", "deser"), + ("drink", "نوشیدنی", "nushidani"), + ("to order", "سفارش دادن", "sefâresh dâdan"), + ("delicious", "خوشمزه", "khoshmaze"), + ("vegetarian", "گیاهخوار", "giyâh-khâr"), + ("the bill please", "صورتحساب لطفا", "surathesâb lotfan"), + ("tip", "انعام", "en'âm"), +]) + +# ── Theme 5: International and global ── +add(S2, "Health", [ + ("health", "سلامت", "salâmat"), + ("illness", "بیماری", "bimâri"), + ("headache", "سردرد", "sardard"), + ("stomach ache", "دل‌درد", "deldard"), + ("fever", "تب", "tab"), + ("cold (illness)", "سرماخوردگی", "sarmâ-khordegi"), + ("medicine", "دارو", "dâru"), + ("hospital", "بیمارستان", "bimârestân"), + ("appointment", "وقت ملاقات", "vaght-e molâghât"), + ("exercise", "ورزش", "varzesh"), + ("healthy", "سالم", "sâlem"), + ("pain", "درد", "dard"), +]) + +add(S2, "Global issues", [ + ("poverty", "فقر", "faghr"), + ("war", "جنگ", "jang"), + ("peace", "صلح", "solh"), + ("equality", "برابری", "barâbari"), + ("education", "آموزش", "âmuzesh"), + ("climate change", "تغییرات آب و هوایی", "taghyirât-e âb va havâyi"), + ("pollution", "آلودگی", "âludegi"), + ("charity", "خیریه", "kheyriye"), + ("rights", "حقوق", "hoghogh"), + ("government", "دولت", "dolat"), +]) + +add(S2, "Technology", [ + ("computer", "کامپیوتر", "kâmpyuter"), + ("phone", "تلفن", "telefon"), + ("mobile phone", "موبایل", "mobâyl"), + ("internet", "اینترنت", "internet"), + ("website", "وبسایت", "vebsâyt"), + ("email", "ایمیل", "imeyl"), + ("screen", "صفحه نمایش", "safhe-ye namâyesh"), + ("to download", "دانلود کردن", "dânlod kardan"), + ("to search", "جستجو کردن", "jostoju kardan"), + ("keyboard", "صفحه کلید", "safhe-ye kelid"), + ("password", "رمز عبور", "ramz-e obur"), + ("application", "برنامه", "barnâme"), +]) + +add(S2, "Social media", [ + ("social media", "شبکه‌های اجتماعی", "shabake-hâ-ye ejtemâ'i"), + ("to share", "به اشتراک گذاشتن", "be eshterâk gozâshtan"), + ("to follow", "دنبال کردن", "donbâl kardan"), + ("to like", "لایک کردن", "lâyk kardan"), + ("message", "پیام", "payâm"), + ("photo", "عکس", "aks"), + ("video", "ویدیو", "vidiyo"), + ("online", "آنلاین", "ânlâyn"), + ("profile", "پروفایل", "profâyl"), + ("to post", "پست کردن", "post kardan"), +]) + +# ── Deduplicate IDs ── +seen_ids = set() +unique_vocab = [] +for entry in vocab: + if entry["id"] in seen_ids: + entry["id"] = entry["id"] + "_2" + if entry["id"] in seen_ids: + entry["id"] = entry["id"] + "_3" + seen_ids.add(entry["id"]) + unique_vocab.append(entry) + +out = Path(__file__).parent.parent / "data" / "vocabulary.json" +out.parent.mkdir(parents=True, exist_ok=True) +with open(out, "w", encoding="utf-8") as f: + json.dump(unique_vocab, f, ensure_ascii=False, indent=2) + +print(f"Generated {len(unique_vocab)} entries → {out}") +cats = {} +for e in unique_vocab: + cats[e["category"]] = cats.get(e["category"], 0) + 1 +for c, n in sorted(cats.items()): + print(f" {c}: {n}") diff --git a/python/persian-tutor/scripts/generate_vocab.py b/python/persian-tutor/scripts/generate_vocab.py new file mode 100644 index 0000000..9c69a4b --- /dev/null +++ b/python/persian-tutor/scripts/generate_vocab.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python3 +"""One-time script to generate/update vocabulary.json with AI-assisted transliterations. + +Usage: + python scripts/generate_vocab.py + +This reads an existing vocabulary.json, finds entries missing finglish +transliterations, and uses Ollama to generate them. +""" + +import json +import sys +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).parent.parent)) +from ai import ask_ollama + +VOCAB_PATH = Path(__file__).parent.parent / "data" / "vocabulary.json" + + +def generate_transliterations(vocab): + """Fill in missing finglish transliterations using AI.""" + missing = [e for e in vocab if not e.get("finglish")] + if not missing: + print("All entries already have finglish transliterations.") + return vocab + + print(f"Generating transliterations for {len(missing)} entries...") + + # Process in batches of 20 + batch_size = 20 + for i in range(0, len(missing), batch_size): + batch = missing[i : i + batch_size] + pairs = "\n".join(f"{e['persian']} = {e['english']}" for e in batch) + + prompt = f"""For each Persian word below, provide the Finglish (romanized) transliteration. +Use these conventions: â for آ, kh for خ, sh for ش, zh for ژ, gh for ق/غ, ch for چ. +Reply with ONLY the transliterations, one per line, in the same order. + +{pairs}""" + + try: + response = ask_ollama(prompt, model="qwen2.5:7b") + lines = [l.strip() for l in response.strip().split("\n") if l.strip()] + + for j, entry in enumerate(batch): + if j < len(lines): + # Clean up the response line + line = lines[j] + # Remove any numbering or equals signs + for sep in ["=", ":", "-", "."]: + if sep in line: + line = line.split(sep)[-1].strip() + entry["finglish"] = line + + print(f" Processed {min(i + batch_size, len(missing))}/{len(missing)}") + except Exception as e: + print(f" Error processing batch: {e}") + + return vocab + + +def main(): + if not VOCAB_PATH.exists(): + print(f"No vocabulary file found at {VOCAB_PATH}") + return + + with open(VOCAB_PATH, encoding="utf-8") as f: + vocab = json.load(f) + + print(f"Loaded {len(vocab)} entries") + vocab = generate_transliterations(vocab) + + with open(VOCAB_PATH, "w", encoding="utf-8") as f: + json.dump(vocab, f, ensure_ascii=False, indent=2) + + print(f"Saved {len(vocab)} entries to {VOCAB_PATH}") + + +if __name__ == "__main__": + main() diff --git a/python/persian-tutor/stt.py b/python/persian-tutor/stt.py new file mode 100644 index 0000000..68f9c91 --- /dev/null +++ b/python/persian-tutor/stt.py @@ -0,0 +1,65 @@ +"""Persian speech-to-text wrapper using sttlib.""" + +import sys + +import numpy as np + +sys.path.insert(0, "/home/ys/family-repo/Code/python/tool-speechtotext") +from sttlib import load_whisper_model, transcribe, is_hallucination + +_model = None + +# Common Whisper hallucinations in Persian/silence +PERSIAN_HALLUCINATIONS = [ + "ممنون", # "thank you" hallucination + "خداحافظ", # "goodbye" hallucination + "تماشا کنید", # "watch" hallucination + "لایک کنید", # "like" hallucination +] + + +def get_model(size="medium"): + """Load Whisper model (cached singleton).""" + global _model + if _model is None: + _model = load_whisper_model(size) + return _model + + +def transcribe_persian(audio_tuple): + """Transcribe Persian audio from Gradio audio component. + + Args: + audio_tuple: (sample_rate, numpy_array) from gr.Audio component. + + Returns: + Transcribed text string, or empty string on failure/hallucination. + """ + if audio_tuple is None: + return "" + + sr, audio = audio_tuple + model = get_model() + + # Convert to float32 normalized [-1, 1] + if audio.dtype == np.int16: + audio_float = audio.astype(np.float32) / 32768.0 + elif audio.dtype == np.float32: + audio_float = audio + else: + audio_float = audio.astype(np.float32) / np.iinfo(audio.dtype).max + + # Mono conversion if stereo + if audio_float.ndim > 1: + audio_float = audio_float.mean(axis=1) + + # Use sttlib transcribe + text = transcribe(model, audio_float) + + # Filter hallucinations (English + Persian) + if is_hallucination(text): + return "" + if text.strip() in PERSIAN_HALLUCINATIONS: + return "" + + return text diff --git a/python/persian-tutor/tests/__init__.py b/python/persian-tutor/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/python/persian-tutor/tests/test_ai.py b/python/persian-tutor/tests/test_ai.py new file mode 100644 index 0000000..fd0df4a --- /dev/null +++ b/python/persian-tutor/tests/test_ai.py @@ -0,0 +1,89 @@ +"""Tests for ai.py — dual AI backend.""" + +import sys +from pathlib import Path +from unittest.mock import patch, MagicMock + +import pytest + +sys.path.insert(0, str(Path(__file__).parent.parent)) + +import ai + + +def test_ask_ollama_calls_ollama_chat(): + """ask_ollama should call ollama.chat with correct messages.""" + mock_response = MagicMock() + mock_response.message.content = "test response" + + with patch("ai.ollama.chat", return_value=mock_response) as mock_chat: + result = ai.ask_ollama("Hello", system="Be helpful") + assert result == "test response" + + call_args = mock_chat.call_args + messages = call_args.kwargs.get("messages") or call_args[1].get("messages") + assert len(messages) == 2 + assert messages[0]["role"] == "system" + assert messages[1]["role"] == "user" + assert messages[1]["content"] == "Hello" + + +def test_ask_ollama_no_system(): + """ask_ollama without system prompt should only send user message.""" + mock_response = MagicMock() + mock_response.message.content = "response" + + with patch("ai.ollama.chat", return_value=mock_response) as mock_chat: + ai.ask_ollama("Hi") + call_args = mock_chat.call_args + messages = call_args.kwargs.get("messages") or call_args[1].get("messages") + assert len(messages) == 1 + assert messages[0]["role"] == "user" + + +def test_ask_claude_calls_subprocess(): + """ask_claude should call claude CLI via subprocess.""" + with patch("ai.subprocess.run") as mock_run: + mock_run.return_value = MagicMock(stdout="Claude says hi\n") + result = ai.ask_claude("Hello") + assert result == "Claude says hi" + mock_run.assert_called_once() + args = mock_run.call_args[0][0] + assert args[0] == "claude" + assert "-p" in args + + +def test_ask_fast_uses_ollama(): + """ask with quality='fast' should use Ollama.""" + with patch("ai.ask_ollama", return_value="ollama response") as mock: + result = ai.ask("test", quality="fast") + assert result == "ollama response" + mock.assert_called_once() + + +def test_ask_smart_uses_claude(): + """ask with quality='smart' should use Claude.""" + with patch("ai.ask_claude", return_value="claude response") as mock: + result = ai.ask("test", quality="smart") + assert result == "claude response" + mock.assert_called_once() + + +def test_chat_ollama(): + """chat_ollama should pass multi-turn messages.""" + mock_response = MagicMock() + mock_response.message.content = "continuation" + + with patch("ai.ollama.chat", return_value=mock_response) as mock_chat: + messages = [ + {"role": "user", "content": "Hi"}, + {"role": "assistant", "content": "Hello!"}, + {"role": "user", "content": "How are you?"}, + ] + result = ai.chat_ollama(messages, system="Be helpful") + assert result == "continuation" + + call_args = mock_chat.call_args + all_msgs = call_args.kwargs.get("messages") or call_args[1].get("messages") + # system + 3 conversation messages + assert len(all_msgs) == 4 diff --git a/python/persian-tutor/tests/test_anki_export.py b/python/persian-tutor/tests/test_anki_export.py new file mode 100644 index 0000000..800c333 --- /dev/null +++ b/python/persian-tutor/tests/test_anki_export.py @@ -0,0 +1,86 @@ +"""Tests for anki_export.py — Anki .apkg generation.""" + +import os +import sys +import tempfile +import zipfile +from pathlib import Path + +import pytest + +sys.path.insert(0, str(Path(__file__).parent.parent)) + +from anki_export import export_deck + +SAMPLE_VOCAB = [ + { + "id": "verb_go", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to go", + "persian": "رفتن", + "finglish": "raftan", + }, + { + "id": "verb_eat", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to eat", + "persian": "خوردن", + "finglish": "khordan", + }, + { + "id": "colour_red", + "section": "High-frequency language", + "category": "Colours", + "english": "red", + "persian": "قرمز", + "finglish": "ghermez", + }, +] + + +def test_export_deck_creates_file(tmp_path): + """export_deck should create a valid .apkg file.""" + output = str(tmp_path / "test.apkg") + result = export_deck(SAMPLE_VOCAB, output_path=output) + assert result == output + assert os.path.exists(output) + assert os.path.getsize(output) > 0 + + +def test_export_deck_is_valid_zip(tmp_path): + """An .apkg file is a zip archive containing an Anki SQLite database.""" + output = str(tmp_path / "test.apkg") + export_deck(SAMPLE_VOCAB, output_path=output) + assert zipfile.is_zipfile(output) + + +def test_export_deck_with_category_filter(tmp_path): + """export_deck with category filter should only include matching entries.""" + output = str(tmp_path / "test.apkg") + export_deck(SAMPLE_VOCAB, categories=["Colours"], output_path=output) + # File should exist and be smaller than unfiltered + assert os.path.exists(output) + size_filtered = os.path.getsize(output) + + output2 = str(tmp_path / "test_all.apkg") + export_deck(SAMPLE_VOCAB, output_path=output2) + size_all = os.path.getsize(output2) + + # Filtered deck should be smaller (fewer cards) + assert size_filtered <= size_all + + +def test_export_deck_empty_vocab(tmp_path): + """export_deck with empty vocabulary should still create a valid file.""" + output = str(tmp_path / "test.apkg") + export_deck([], output_path=output) + assert os.path.exists(output) + + +def test_export_deck_no_category_match(tmp_path): + """export_deck with non-matching category filter should create empty deck.""" + output = str(tmp_path / "test.apkg") + export_deck(SAMPLE_VOCAB, categories=["Nonexistent"], output_path=output) + assert os.path.exists(output) diff --git a/python/persian-tutor/tests/test_db.py b/python/persian-tutor/tests/test_db.py new file mode 100644 index 0000000..2417b76 --- /dev/null +++ b/python/persian-tutor/tests/test_db.py @@ -0,0 +1,151 @@ +"""Tests for db.py — SQLite database layer with FSRS integration.""" + +import os +import sys +import tempfile +from pathlib import Path +from unittest.mock import patch + +import pytest + +# Add project root to path +sys.path.insert(0, str(Path(__file__).parent.parent)) + +import fsrs + + +@pytest.fixture(autouse=True) +def temp_db(tmp_path): + """Use a temporary database for each test.""" + import db as db_mod + + db_mod._conn = None + db_mod.DB_PATH = tmp_path / "test.db" + db_mod.init_db() + yield db_mod + db_mod.close() + + +def test_init_db_creates_tables(temp_db): + """init_db should create all required tables.""" + conn = temp_db.get_connection() + tables = conn.execute( + "SELECT name FROM sqlite_master WHERE type='table'" + ).fetchall() + table_names = {row["name"] for row in tables} + assert "word_progress" in table_names + assert "quiz_sessions" in table_names + assert "essays" in table_names + assert "tutor_sessions" in table_names + + +def test_get_word_progress_nonexistent(temp_db): + """Should return None for a word that hasn't been reviewed.""" + assert temp_db.get_word_progress("nonexistent") is None + + +def test_update_and_get_word_progress(temp_db): + """update_word_progress should create and update progress.""" + card = temp_db.update_word_progress("verb_go", fsrs.Rating.Good) + assert card is not None + assert card.stability is not None + + progress = temp_db.get_word_progress("verb_go") + assert progress is not None + assert progress["word_id"] == "verb_go" + assert progress["reps"] == 1 + assert progress["fsrs_state"] is not None + + +def test_update_word_progress_increments_reps(temp_db): + """Reviewing the same word multiple times should increment reps.""" + temp_db.update_word_progress("verb_go", fsrs.Rating.Good) + temp_db.update_word_progress("verb_go", fsrs.Rating.Easy) + progress = temp_db.get_word_progress("verb_go") + assert progress["reps"] == 2 + + +def test_get_due_words(temp_db): + """get_due_words should return words that are due for review.""" + # A newly reviewed word with Rating.Again should be due soon + temp_db.update_word_progress("verb_go", fsrs.Rating.Again) + # An easy word should have a later due date + temp_db.update_word_progress("verb_eat", fsrs.Rating.Easy) + + # Due words depend on timing; at minimum both should be in the system + all_progress = temp_db.get_connection().execute( + "SELECT word_id FROM word_progress" + ).fetchall() + assert len(all_progress) == 2 + + +def test_get_word_counts(temp_db): + """get_word_counts should return correct counts.""" + counts = temp_db.get_word_counts(total_vocab_size=100) + assert counts["total"] == 100 + assert counts["seen"] == 0 + assert counts["mastered"] == 0 + assert counts["due"] == 0 + + temp_db.update_word_progress("verb_go", fsrs.Rating.Good) + counts = temp_db.get_word_counts(total_vocab_size=100) + assert counts["seen"] == 1 + + +def test_record_quiz_session(temp_db): + """record_quiz_session should insert a quiz record.""" + temp_db.record_quiz_session("Common verbs", 10, 7, 120) + rows = temp_db.get_connection().execute( + "SELECT * FROM quiz_sessions" + ).fetchall() + assert len(rows) == 1 + assert rows[0]["correct"] == 7 + assert rows[0]["total_questions"] == 10 + + +def test_save_essay(temp_db): + """save_essay should store the essay and feedback.""" + temp_db.save_essay("متن آزمایشی", "B1", "Good effort!", "Identity and culture") + essays = temp_db.get_recent_essays() + assert len(essays) == 1 + assert essays[0]["grade"] == "B1" + + +def test_save_tutor_session(temp_db): + """save_tutor_session should store the conversation.""" + messages = [ + {"role": "user", "content": "سلام"}, + {"role": "assistant", "content": "سلام! حالت چطوره؟"}, + ] + temp_db.save_tutor_session("Identity and culture", messages, 300) + rows = temp_db.get_connection().execute( + "SELECT * FROM tutor_sessions" + ).fetchall() + assert len(rows) == 1 + assert rows[0]["theme"] == "Identity and culture" + + +def test_get_stats(temp_db): + """get_stats should return aggregated stats.""" + stats = temp_db.get_stats() + assert stats["total_reviews"] == 0 + assert stats["total_quizzes"] == 0 + assert stats["streak"] == 0 + assert isinstance(stats["recent_quizzes"], list) + + +def test_close_and_reopen(temp_db): + """Closing and reopening should preserve data.""" + temp_db.update_word_progress("verb_go", fsrs.Rating.Good) + db_path = temp_db.DB_PATH + + temp_db.close() + + # Reopen + temp_db._conn = None + temp_db.DB_PATH = db_path + temp_db.init_db() + + progress = temp_db.get_word_progress("verb_go") + assert progress is not None + assert progress["reps"] == 1 diff --git a/python/persian-tutor/tests/test_vocab.py b/python/persian-tutor/tests/test_vocab.py new file mode 100644 index 0000000..cb45cbf --- /dev/null +++ b/python/persian-tutor/tests/test_vocab.py @@ -0,0 +1,204 @@ +"""Tests for modules/vocab.py — vocabulary search and flashcard logic.""" + +import json +import sys +from pathlib import Path +from unittest.mock import patch + +import pytest + +sys.path.insert(0, str(Path(__file__).parent.parent)) + +SAMPLE_VOCAB = [ + { + "id": "verb_go", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to go", + "persian": "رفتن", + "finglish": "raftan", + }, + { + "id": "verb_eat", + "section": "High-frequency language", + "category": "Common verbs", + "english": "to eat", + "persian": "خوردن", + "finglish": "khordan", + }, + { + "id": "adj_big", + "section": "High-frequency language", + "category": "Common adjectives", + "english": "big", + "persian": "بزرگ", + "finglish": "bozorg", + }, + { + "id": "colour_red", + "section": "High-frequency language", + "category": "Colours", + "english": "red", + "persian": "قرمز", + "finglish": "ghermez", + }, +] + + +@pytest.fixture(autouse=True) +def mock_vocab_and_db(tmp_path): + """Mock vocabulary loading and use temp DB.""" + import db as db_mod + import modules.vocab as vocab_mod + + # Temp DB + db_mod._conn = None + db_mod.DB_PATH = tmp_path / "test.db" + db_mod.init_db() + + # Mock vocab + vocab_mod._vocab_data = SAMPLE_VOCAB + + yield vocab_mod + + db_mod.close() + vocab_mod._vocab_data = None + + +def test_load_vocab(mock_vocab_and_db): + """load_vocab should return the vocabulary data.""" + data = mock_vocab_and_db.load_vocab() + assert len(data) == 4 + + +def test_get_categories(mock_vocab_and_db): + """get_categories should return unique sorted categories.""" + cats = mock_vocab_and_db.get_categories() + assert "Colours" in cats + assert "Common verbs" in cats + assert "Common adjectives" in cats + + +def test_search_english(mock_vocab_and_db): + """Search should find entries by English text.""" + results = mock_vocab_and_db.search("go") + assert len(results) == 1 + assert results[0]["id"] == "verb_go" + + +def test_search_persian(mock_vocab_and_db): + """Search should find entries by Persian text.""" + results = mock_vocab_and_db.search("رفتن") + assert len(results) == 1 + assert results[0]["id"] == "verb_go" + + +def test_search_finglish(mock_vocab_and_db): + """Search should find entries by Finglish text.""" + results = mock_vocab_and_db.search("raftan") + assert len(results) == 1 + assert results[0]["id"] == "verb_go" + + +def test_search_empty(mock_vocab_and_db): + """Empty search should return empty list.""" + assert mock_vocab_and_db.search("") == [] + assert mock_vocab_and_db.search(None) == [] + + +def test_search_no_match(mock_vocab_and_db): + """Search with no match should return empty list.""" + assert mock_vocab_and_db.search("zzzzz") == [] + + +def test_get_random_word(mock_vocab_and_db): + """get_random_word should return a valid entry.""" + word = mock_vocab_and_db.get_random_word() + assert word is not None + assert "id" in word + assert "english" in word + assert "persian" in word + + +def test_get_random_word_with_category(mock_vocab_and_db): + """get_random_word with category filter should only return matching entries.""" + word = mock_vocab_and_db.get_random_word(category="Colours") + assert word is not None + assert word["category"] == "Colours" + + +def test_get_random_word_nonexistent_category(mock_vocab_and_db): + """get_random_word with bad category should return None.""" + word = mock_vocab_and_db.get_random_word(category="Nonexistent") + assert word is None + + +def test_check_answer_correct_en_to_fa(mock_vocab_and_db): + """Correct Persian answer should be marked correct.""" + correct, answer, entry = mock_vocab_and_db.check_answer( + "verb_go", "رفتن", direction="en_to_fa" + ) + assert correct is True + + +def test_check_answer_incorrect_en_to_fa(mock_vocab_and_db): + """Incorrect Persian answer should be marked incorrect with correct answer.""" + correct, answer, entry = mock_vocab_and_db.check_answer( + "verb_go", "خوردن", direction="en_to_fa" + ) + assert correct is False + assert answer == "رفتن" + + +def test_check_answer_fa_to_en(mock_vocab_and_db): + """Correct English answer (case-insensitive) should be marked correct.""" + correct, answer, entry = mock_vocab_and_db.check_answer( + "verb_go", "To Go", direction="fa_to_en" + ) + assert correct is True + + +def test_check_answer_nonexistent_word(mock_vocab_and_db): + """Checking answer for nonexistent word should return False.""" + correct, answer, entry = mock_vocab_and_db.check_answer( + "nonexistent", "test", direction="en_to_fa" + ) + assert correct is False + assert entry is None + + +def test_format_word_card(mock_vocab_and_db): + """format_word_card should produce RTL HTML with correct content.""" + entry = SAMPLE_VOCAB[0] + html = mock_vocab_and_db.format_word_card(entry, show_transliteration="Finglish") + assert "رفتن" in html + assert "to go" in html + assert "raftan" in html + + +def test_format_word_card_no_transliteration(mock_vocab_and_db): + """format_word_card with transliteration off should not show finglish.""" + entry = SAMPLE_VOCAB[0] + html = mock_vocab_and_db.format_word_card(entry, show_transliteration="off") + assert "raftan" not in html + + +def test_get_flashcard_batch(mock_vocab_and_db): + """get_flashcard_batch should return a batch of entries.""" + batch = mock_vocab_and_db.get_flashcard_batch(count=2) + assert len(batch) == 2 + assert all("id" in e for e in batch) + + +def test_get_word_status_new(mock_vocab_and_db): + """Unreviewed word should have status 'new'.""" + assert mock_vocab_and_db.get_word_status("verb_go") == "new" + + +def test_get_word_status_learning(mock_vocab_and_db): + """Recently reviewed word should have status 'learning'.""" + import db + import fsrs + + db.update_word_progress("verb_go", fsrs.Rating.Good) + assert mock_vocab_and_db.get_word_status("verb_go") == "learning"