rafaym commited on
Commit
0807ad2
·
verified ·
1 Parent(s): 9d56ac6

Initial upload — Legesher native code submission portal

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ wheels/legesher_i18n-0.7.3-py3-none-any.whl filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -1,12 +1,60 @@
1
  ---
2
- title: Legesher Native Code
3
  emoji: 🌍
4
- colorFrom: pink
5
- colorTo: blue
6
  sdk: gradio
7
  sdk_version: 6.11.0
8
  app_file: app.py
9
  pinned: false
10
  ---
11
 
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: Legesher Native Code Submission
3
  emoji: 🌍
4
+ colorFrom: blue
5
+ colorTo: green
6
  sdk: gradio
7
  sdk_version: 6.11.0
8
  app_file: app.py
9
  pinned: false
10
  ---
11
 
12
+ # Native Code Submission Portal
13
+
14
+ A Gradio web app for collecting natively-written Legesher Python code from native speakers of Chinese, Spanish, and Urdu.
15
+
16
+ Part of **Language, Decoded — Expedition Tiny Aya** (Condition 4: Strictly Native Code).
17
+
18
+ ---
19
+
20
+ ## What this does
21
+
22
+ Contributors open the app, pick an exercise, write their solution in their native language using Legesher, run it to confirm it works, then submit. Submissions are saved to a HuggingFace dataset.
23
+
24
+ The app uses the Legesher Python API (`TokenTranslator`) to transpile native-language code to standard Python for execution — so contributors can see their code actually run in the browser.
25
+
26
+ ---
27
+
28
+ ## Run locally
29
+
30
+ **Prerequisites:** Python 3.10+
31
+
32
+ ```bash
33
+ cd native-code-submission
34
+ pip install -r requirements.txt
35
+ python app.py
36
+ ```
37
+
38
+ ---
39
+
40
+ ## Folder structure
41
+
42
+ ```
43
+ native-code-submission/
44
+ ├── app.py # Main Gradio app
45
+ ├── exercises.json # Exercise prompts (zh/es/ur, tiers 1–3)
46
+ ├── requirements.txt # Python dependencies
47
+ ├── references/ # Legesher keyword reference per language
48
+ │ ├── zh.md
49
+ │ ├── es.md
50
+ │ └── ur.md
51
+ └── wheels/ # Bundled Legesher wheels (not on PyPI)
52
+ ```
53
+
54
+ ---
55
+
56
+ ## Related issues
57
+
58
+ - AYA-128 — Exercise design (Done)
59
+ - AYA-129 — Native code criteria (Done) — [criteria doc](https://linear.app/legesher-research/document/native-code-criteria-qualification-disqualification-and-quality-rubric-5705fc83d6e8)
60
+ - AYA-127 — Submission flow design (this)
app.py ADDED
@@ -0,0 +1,470 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Native Code Submission Portal — Language, Decoded / Expedition Tiny Aya
3
+ =======================================================================
4
+ A Gradio app for collecting natively-written Legesher code from
5
+ native speakers of Chinese, Spanish, and Urdu.
6
+
7
+ Contributors write Python in their native language using Legesher,
8
+ run it to verify it works, then submit it for research use.
9
+
10
+ HF Space secrets required:
11
+ HF_TOKEN — write token for pushing submissions to the dataset repo
12
+ HF_DATASET_ID — target dataset repo (e.g. "legesher-research/native-code-submissions")
13
+ """
14
+
15
+ import json
16
+ import logging
17
+ import os
18
+ import subprocess
19
+ import sys
20
+ import tempfile
21
+ import uuid
22
+ from datetime import datetime, timezone
23
+ from pathlib import Path
24
+
25
+ import gradio as gr
26
+
27
+ logging.basicConfig(level=logging.INFO)
28
+ logger = logging.getLogger(__name__)
29
+
30
+ # ---------------------------------------------------------------------------
31
+ # Legesher setup
32
+ # ---------------------------------------------------------------------------
33
+
34
+ try:
35
+ from legesher_core import TokenTranslator
36
+ LEGESHER_OK = True
37
+ logger.info("Legesher loaded successfully.")
38
+ except ImportError as e:
39
+ LEGESHER_OK = False
40
+ logger.warning(f"Legesher not available: {e}. Run/translate disabled.")
41
+
42
+ # Cache translators so we don't reload on every button click
43
+ _translators: dict[str, TokenTranslator] = {}
44
+
45
+ def _get_native_to_en(lang: str) -> TokenTranslator:
46
+ if lang not in _translators:
47
+ en_to_native = TokenTranslator.from_language_pack(lang)
48
+ _translators[lang] = en_to_native.reverse()
49
+ return _translators[lang]
50
+
51
+ # ---------------------------------------------------------------------------
52
+ # Exercises
53
+ # ---------------------------------------------------------------------------
54
+
55
+ EXERCISES_PATH = Path(__file__).parent / "exercises.json"
56
+ with open(EXERCISES_PATH, encoding="utf-8") as _f:
57
+ _ALL_EXERCISES: dict = json.load(_f)
58
+
59
+ TIER_KEYS = ["tier1", "tier2", "tier3"]
60
+ TIER_LABELS = ["Tier 1 — Basic (10–20 lines)", "Tier 2 — Applied (20–50 lines)", "Tier 3 — Domain (50–100 lines)"]
61
+
62
+ LANGUAGES = {
63
+ "zh": "中文 (Chinese)",
64
+ "es": "Español (Spanish)",
65
+ "ur": "اردو (Urdu)",
66
+ }
67
+
68
+ # Reverse map: display label -> code (handles Gradio 6 returning label instead of value)
69
+ _LABEL_TO_CODE = {v: k for k, v in LANGUAGES.items()}
70
+
71
+ # ---------------------------------------------------------------------------
72
+ # Keyword reference — loaded from REFERENCE.md files per language
73
+ # ---------------------------------------------------------------------------
74
+
75
+ _REFERENCES_DIR = Path(__file__).parent / "references"
76
+
77
+ def load_reference(lang: str) -> str:
78
+ """Load the Legesher REFERENCE.md for the given language."""
79
+ path = _REFERENCES_DIR / f"{lang}.md"
80
+ if path.exists():
81
+ return path.read_text(encoding="utf-8")
82
+ return f"_Reference file not found for `{lang}`._"
83
+
84
+ def normalize_lang(lang_input: str) -> str:
85
+ """Accept either a language code ('ur') or display label ('اردو (Urdu)') and return the code."""
86
+ if lang_input in LANGUAGES:
87
+ return lang_input
88
+ if lang_input in _LABEL_TO_CODE:
89
+ return _LABEL_TO_CODE[lang_input]
90
+ logger.warning(f"Unknown lang input: {lang_input!r}, falling back to zh")
91
+ return "zh"
92
+
93
+ def get_exercise_choices(lang: str, tier_idx: int) -> list[str]:
94
+ tier_key = TIER_KEYS[tier_idx]
95
+ exercises = _ALL_EXERCISES.get(lang, {}).get(tier_key, [])
96
+ return [ex["title"] for ex in exercises]
97
+
98
+ def get_exercise(lang: str, tier_idx: int, title: str) -> dict | None:
99
+ tier_key = TIER_KEYS[tier_idx]
100
+ for ex in _ALL_EXERCISES.get(lang, {}).get(tier_key, []):
101
+ if ex["title"] == title:
102
+ return ex
103
+ return None
104
+
105
+ # ---------------------------------------------------------------------------
106
+ # HuggingFace dataset submission
107
+ # ---------------------------------------------------------------------------
108
+
109
+ HF_TOKEN = os.environ.get("HF_TOKEN", "")
110
+ HF_DATASET_ID = os.environ.get("HF_DATASET_ID", "legesher-research/native-code-submissions")
111
+
112
+ def push_submission(row: dict) -> bool:
113
+ """Push a single submission row to the HF dataset as a JSONL entry."""
114
+ if not HF_TOKEN:
115
+ logger.warning("HF_TOKEN not set — submission not saved to HF.")
116
+ return False
117
+ try:
118
+ from huggingface_hub import HfApi
119
+ api = HfApi(token=HF_TOKEN)
120
+ filename = f"submissions/{row['language']}/{row['id']}.json"
121
+ content = json.dumps(row, ensure_ascii=False, indent=2).encode("utf-8")
122
+ api.upload_file(
123
+ path_or_fileobj=content,
124
+ path_in_repo=filename,
125
+ repo_id=HF_DATASET_ID,
126
+ repo_type="dataset",
127
+ commit_message=f"[submission] {row['language']} {row['exercise_id']} {row['id'][:8]}",
128
+ )
129
+ return True
130
+ except Exception as e:
131
+ logger.error(f"HF upload failed: {e}")
132
+ return False
133
+
134
+ # ---------------------------------------------------------------------------
135
+ # Core actions
136
+ # ---------------------------------------------------------------------------
137
+
138
+ def run_code(code: str, lang: str, stdin: str = "") -> str:
139
+ """Translate native code to English Python and execute it safely."""
140
+ lang = normalize_lang(lang)
141
+ if not code.strip():
142
+ return "Write some code first."
143
+ if not LEGESHER_OK:
144
+ return "Legesher is not available in this environment. Code execution disabled."
145
+
146
+ try:
147
+ translator = _get_native_to_en(lang)
148
+ english_code = translator.translate_code(code)
149
+ except Exception as e:
150
+ return f"Translation error: {e}"
151
+
152
+ try:
153
+ with tempfile.NamedTemporaryFile(
154
+ mode="w", suffix=".py", delete=False, encoding="utf-8"
155
+ ) as tmp:
156
+ tmp.write(english_code)
157
+ tmp_path = tmp.name
158
+
159
+ result = subprocess.run(
160
+ [sys.executable, "-X", "utf8", tmp_path],
161
+ input=stdin if stdin.strip() else None,
162
+ capture_output=True,
163
+ text=True,
164
+ timeout=10,
165
+ encoding="utf-8",
166
+ env={**os.environ, "PYTHONIOENCODING": "utf-8", "PYTHONUTF8": "1"},
167
+ )
168
+ os.unlink(tmp_path)
169
+
170
+ out = result.stdout.strip()
171
+ err = result.stderr.strip()
172
+ if err:
173
+ out = (out + "\n\n⚠️ Errors:\n" + err).strip()
174
+ return out or "(no output — did you call your function at the bottom?)"
175
+
176
+ except subprocess.TimeoutExpired:
177
+ return "Timed out after 10 seconds. Check for infinite loops or missing input."
178
+ except Exception as e:
179
+ return f"Execution error: {e}"
180
+
181
+
182
+ def submit_code(
183
+ code: str,
184
+ lang: str, # normalized below
185
+ tier_idx: int,
186
+ exercise_title: str,
187
+ time_spent: int,
188
+ consent: bool,
189
+ ) -> str:
190
+ lang = normalize_lang(lang)
191
+ if not consent:
192
+ return "Please tick the consent checkbox before submitting."
193
+ if not code.strip():
194
+ return "Code is empty — nothing to submit."
195
+ if not exercise_title:
196
+ return "Select an exercise before submitting."
197
+
198
+ ex = get_exercise(lang, tier_idx, exercise_title)
199
+ exercise_id = ex["id"] if ex else f"{lang}-unknown"
200
+
201
+ row = {
202
+ "id": str(uuid.uuid4()),
203
+ "code": code,
204
+ "language": lang,
205
+ "exercise_id": exercise_id,
206
+ "exercise_title": exercise_title,
207
+ "tier": tier_idx + 1,
208
+ "time_spent_minutes": time_spent,
209
+ "submitted_at": datetime.now(timezone.utc).isoformat(),
210
+ "consent_given": True,
211
+ "legesher_version": "0.7.3",
212
+ }
213
+
214
+ saved = push_submission(row)
215
+ if saved:
216
+ return f"Submitted! Your contribution ID: `{row['id'][:8]}`. Thank you for contributing to Language, Decoded."
217
+ else:
218
+ # Fallback: save locally so nothing is lost
219
+ fallback_dir = Path(__file__).parent / "local_submissions"
220
+ fallback_dir.mkdir(exist_ok=True)
221
+ (fallback_dir / f"{row['id']}.json").write_text(
222
+ json.dumps(row, ensure_ascii=False, indent=2), encoding="utf-8"
223
+ )
224
+ return f"Saved locally (HF upload unavailable). ID: `{row['id'][:8]}`."
225
+
226
+ # ---------------------------------------------------------------------------
227
+ # UI helpers
228
+ # ---------------------------------------------------------------------------
229
+
230
+ def update_exercise_dropdown(lang: str, tier_idx: int):
231
+ choices = get_exercise_choices(lang, tier_idx)
232
+ value = choices[0] if choices else None
233
+ return gr.update(choices=choices, value=value)
234
+
235
+ def update_prompt(lang: str, tier_idx: int, exercise_title: str) -> str:
236
+ if not exercise_title:
237
+ return ""
238
+ ex = get_exercise(lang, tier_idx, exercise_title)
239
+ if not ex:
240
+ return ""
241
+ time_note = f"*Estimated time: ~{ex['time_estimate_min']} minutes*\n\n"
242
+ return time_note + ex["prompt"]
243
+
244
+ def update_on_lang_change(lang: str, tier_idx: int):
245
+ choices = get_exercise_choices(lang, tier_idx)
246
+ value = choices[0] if choices else None
247
+ prompt = update_prompt(lang, tier_idx, value) if value else ""
248
+ return gr.Dropdown(choices=choices, value=value), prompt
249
+
250
+ # ---------------------------------------------------------------------------
251
+ # Gradio UI
252
+ # ---------------------------------------------------------------------------
253
+
254
+ HEADER_MD = """
255
+ # Native Code Contribution Portal
256
+ ### Language, Decoded — Expedition Tiny Aya
257
+
258
+ Write Python code in your native language using [Legesher](https://legesher.io) and contribute to our research on native-language programming.
259
+
260
+ **How it works:**
261
+ 1. Select your language and an exercise
262
+ 2. Write your solution using Legesher (native keywords + native variable names)
263
+ 3. Click **Run** to verify your code works
264
+ 4. Fill in the metadata and click **Submit**
265
+
266
+ ---
267
+ """
268
+
269
+ CONSENT_TEXT = (
270
+ "I give permission for my submitted code to be used in the Language, Decoded research project "
271
+ "and to be published as part of an open dataset (Apache 2.0 / CC-BY-4.0). "
272
+ "No personal information is collected — submissions are anonymous."
273
+ )
274
+
275
+ SIDEBAR_MD = """
276
+ ### What counts as native code?
277
+
278
+ - Variables, functions, and classes named in your language
279
+ - Written from scratch — not translated from an English solution
280
+ - Reflects how *you* would naturally think about the problem
281
+ - Uses Legesher keywords throughout
282
+
283
+ ### What doesn't qualify?
284
+
285
+ - Word-for-word translations of English code
286
+ - AI-generated code
287
+ - English variable names with only keywords swapped
288
+
289
+ Need help? Read the full [criteria document](https://linear.app/legesher-research/document/native-code-criteria-qualification-disqualification-and-quality-rubric-5705fc83d6e8).
290
+ """
291
+
292
+ def build_app() -> gr.Blocks:
293
+ with gr.Blocks(title="Native Code Submission — Language, Decoded") as app:
294
+
295
+ gr.Markdown(HEADER_MD)
296
+
297
+ with gr.Row():
298
+ # ---- Left column: config + exercise ----
299
+ with gr.Column(scale=1):
300
+ lang_dropdown = gr.Dropdown(
301
+ label="Your language",
302
+ choices=[(v, k) for k, v in LANGUAGES.items()],
303
+ value="zh",
304
+ )
305
+
306
+ tier_radio = gr.Radio(
307
+ label="Exercise tier",
308
+ choices=TIER_LABELS,
309
+ value=TIER_LABELS[0],
310
+ )
311
+
312
+ exercise_dropdown = gr.Dropdown(
313
+ label="Exercise",
314
+ choices=get_exercise_choices("zh", 0),
315
+ value=get_exercise_choices("zh", 0)[0],
316
+ )
317
+
318
+ exercise_prompt = gr.Markdown(
319
+ value=update_prompt("zh", 0, get_exercise_choices("zh", 0)[0]),
320
+ label="Exercise prompt",
321
+ )
322
+
323
+ gr.Markdown(SIDEBAR_MD)
324
+
325
+ with gr.Accordion("Legesher keyword reference", open=False):
326
+ cheatsheet = gr.Markdown(
327
+ value=load_reference("zh"),
328
+ )
329
+
330
+ # ---- Right column: editor + run + submit ----
331
+ with gr.Column(scale=2):
332
+ code_editor = gr.Code(
333
+ label="Your Legesher code",
334
+ language="python",
335
+ lines=20,
336
+ value="# Write your solution here using Legesher\n# Use native-language variable and function names\n",
337
+ )
338
+
339
+ with gr.Row():
340
+ run_btn = gr.Button("Run code", variant="secondary")
341
+ clear_btn = gr.Button("Clear", variant="stop")
342
+
343
+ stdin_input = gr.Textbox(
344
+ label="Program input (stdin) — one value per line",
345
+ placeholder="e.g. 15\n(leave blank if your code needs no input)",
346
+ lines=2,
347
+ )
348
+
349
+ run_output = gr.Textbox(
350
+ label="Output",
351
+ lines=6,
352
+ placeholder="Run your code to see output here...",
353
+ interactive=False,
354
+ )
355
+
356
+ gr.Markdown("---")
357
+ gr.Markdown("### Submit your solution")
358
+
359
+ time_slider = gr.Slider(
360
+ label="Time spent (minutes)",
361
+ minimum=1,
362
+ maximum=120,
363
+ step=1,
364
+ value=15,
365
+ )
366
+
367
+ consent_checkbox = gr.Checkbox(
368
+ label=CONSENT_TEXT,
369
+ value=False,
370
+ )
371
+
372
+ submit_btn = gr.Button("Submit contribution", variant="primary")
373
+
374
+ submit_status = gr.Textbox(
375
+ label="Submission status",
376
+ interactive=False,
377
+ )
378
+
379
+ # ---- State ----
380
+ tier_idx_state = gr.State(value=0)
381
+ lang_state = gr.State(value="zh")
382
+
383
+ # ---- Event wiring ----
384
+
385
+ def tier_to_idx(tier_label: str) -> int:
386
+ return TIER_LABELS.index(tier_label)
387
+
388
+ def on_tier_change(tier_label: str, lang: str):
389
+ try:
390
+ idx = TIER_LABELS.index(tier_label) if tier_label in TIER_LABELS else 0
391
+ choices = get_exercise_choices(lang, idx)
392
+ value = choices[0] if choices else None
393
+ prompt = update_prompt(lang, idx, value) if value else ""
394
+ return idx, gr.update(choices=choices, value=value), prompt
395
+ except Exception as e:
396
+ logger.error(f"on_tier_change error: {e!r} | tier_label={tier_label!r} lang={lang!r}")
397
+ return 0, gr.update(), ""
398
+
399
+ def on_lang_change(lang_raw: str, tier_label: str):
400
+ try:
401
+ lang_code = normalize_lang(lang_raw)
402
+ logger.info(f"on_lang_change: raw={lang_raw!r} -> code={lang_code!r} tier={tier_label!r}")
403
+ idx = TIER_LABELS.index(tier_label) if tier_label in TIER_LABELS else 0
404
+ choices = get_exercise_choices(lang_code, idx)
405
+ value = choices[0] if choices else None
406
+ prompt = update_prompt(lang_code, idx, value) if value else ""
407
+ sheet = load_reference(lang_code)
408
+ logger.info(f"on_lang_change OK: choices={choices}")
409
+ return lang_code, gr.update(choices=choices, value=value), prompt, sheet
410
+ except Exception as e:
411
+ logger.error(f"on_lang_change error: {e!r} | lang_raw={lang_raw!r}")
412
+ return "zh", gr.update(), "", load_reference("zh")
413
+
414
+ def on_exercise_change(exercise_title: str, lang_raw: str, tier_idx: int):
415
+ # Use lang_dropdown value directly (always current), not lang_state (can be stale)
416
+ try:
417
+ lang_code = normalize_lang(lang_raw)
418
+ return update_prompt(lang_code, tier_idx, exercise_title)
419
+ except Exception as e:
420
+ logger.error(f"on_exercise_change error: {e!r}")
421
+ return ""
422
+
423
+ lang_dropdown.change(
424
+ on_lang_change,
425
+ inputs=[lang_dropdown, tier_radio],
426
+ outputs=[lang_state, exercise_dropdown, exercise_prompt, cheatsheet],
427
+ )
428
+
429
+ tier_radio.change(
430
+ on_tier_change,
431
+ inputs=[tier_radio, lang_state],
432
+ outputs=[tier_idx_state, exercise_dropdown, exercise_prompt],
433
+ )
434
+
435
+ exercise_dropdown.change(
436
+ on_exercise_change,
437
+ inputs=[exercise_dropdown, lang_dropdown, tier_idx_state],
438
+ outputs=[exercise_prompt],
439
+ )
440
+
441
+ run_btn.click(
442
+ fn=run_code,
443
+ inputs=[code_editor, lang_state, stdin_input],
444
+ outputs=[run_output],
445
+ )
446
+
447
+ clear_btn.click(
448
+ fn=lambda: ("", "", ""),
449
+ outputs=[code_editor, stdin_input, run_output],
450
+ )
451
+
452
+ submit_btn.click(
453
+ fn=submit_code,
454
+ inputs=[
455
+ code_editor,
456
+ lang_state,
457
+ tier_idx_state,
458
+ exercise_dropdown,
459
+ time_slider,
460
+ consent_checkbox,
461
+ ],
462
+ outputs=[submit_status],
463
+ )
464
+
465
+ return app
466
+
467
+
468
+ if __name__ == "__main__":
469
+ app = build_app()
470
+ app.launch(theme=gr.themes.Soft(primary_hue="blue"))
exercises.json ADDED
@@ -0,0 +1,170 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "zh": {
3
+ "tier1": [
4
+ {
5
+ "id": "zh-t1-fizzbuzz",
6
+ "title": "FizzBuzz",
7
+ "tier": 1,
8
+ "prompt": "写一个程序,打印从 1 到 30 的数字。\n\n规则:\n- 如果数字能被 3 整除,打印 \"嘶嘶\" 而不是数字\n- 如果数字能被 5 整除,打印 \"嗡嗡\" 而不是数字\n- 如果数字既能被 3 又能被 5 整除,打印 \"嘶嘶嗡嗡\"\n\n预期输出示例:1, 2, 嘶嘶, 4, 嗡嗡, 嘶嘶, 7, ...",
9
+ "expected_output": "1\n2\n嘶嘶\n4\n嗡嗡\n嘶嘶\n7\n8\n嘶嘶\n嗡嗡\n11\n嘶嘶\n13\n14\n嘶嘶嗡嗡",
10
+ "time_estimate_min": 10
11
+ },
12
+ {
13
+ "id": "zh-t1-factorial",
14
+ "title": "阶乘",
15
+ "tier": 1,
16
+ "prompt": "写一个函数,计算一个正整数的阶乘。\n\n例如:\n- 阶乘(5) → 120\n- 阶乘(0) → 1\n- 阶乘(7) → 5040\n\n提示:阶乘(n) = n × (n-1) × ... × 1",
17
+ "expected_output": "120\n1\n5040",
18
+ "time_estimate_min": 10
19
+ },
20
+ {
21
+ "id": "zh-t1-palindrome",
22
+ "title": "回文检测",
23
+ "tier": 1,
24
+ "prompt": "写一个函数,检测一个字符串是否是回文(正读反读都一样)。\n\n例如:\n- \"racecar\" → 是回文\n- \"hello\" → 不是回文\n- \"上海自来水来自海上\" → 是回文\n\n忽略大小写和空格。",
25
+ "expected_output": "是\n否\n是",
26
+ "time_estimate_min": 15
27
+ }
28
+ ],
29
+ "tier2": [
30
+ {
31
+ "id": "zh-t2-calculator",
32
+ "title": "计算器",
33
+ "tier": 2,
34
+ "prompt": "写一个简单的命令行计算器,支持以下功能:\n\n- 加法、减法、乘法、除法\n- 处理除以零的错误\n- 循环接受用户输入,直到用户输入 '退出'\n\n输入格式:\"数字 运算符 数字\"(例如:\"10 + 5\")",
35
+ "expected_output": "计算器已启动(输入'退出'结束)\n>>> 10 + 5 = 15",
36
+ "time_estimate_min": 25
37
+ },
38
+ {
39
+ "id": "zh-t2-word-count",
40
+ "title": "词频统计",
41
+ "tier": 2,
42
+ "prompt": "写一个程序,统计一段文字中每个词出现的频率,并按频率从高到低排序输出前 10 个词。\n\n输入:一段中文或英文文字(可以硬编码在程序中)\n输出:词语及其出现次数,按频率排序",
43
+ "expected_output": "词频统计结果:\n\"的\": 15次\n\"是\": 12次\n...",
44
+ "time_estimate_min": 30
45
+ }
46
+ ],
47
+ "tier3": [
48
+ {
49
+ "id": "zh-t3-data-analysis",
50
+ "title": "数据分析脚本",
51
+ "tier": 3,
52
+ "prompt": "写一个数据分析脚本,分析一组学生成绩数据。\n\n功能要求:\n1. 定义一组学生数据(姓名 + 成绩列表,至少 10 名学生)\n2. 计算班级平均分、最高分、最低分\n3. 按成绩分组(优秀 90+、良好 75-89、及格 60-74、不及格 <60)\n4. 找出成绩高于平均分的学生\n5. 输出完整报告",
53
+ "expected_output": "班级成绩分析报告\n=================\n平均分:78.5\n最高分:98(李明)\n最低分:45(王芳)\n...",
54
+ "time_estimate_min": 45
55
+ }
56
+ ]
57
+ },
58
+ "es": {
59
+ "tier1": [
60
+ {
61
+ "id": "es-t1-fizzbuzz",
62
+ "title": "FizzBuzz",
63
+ "tier": 1,
64
+ "prompt": "Escribe un programa que imprima los números del 1 al 30.\n\nReglas:\n- Si el número es divisible entre 3, imprime \"Fizz\" en lugar del número\n- Si el número es divisible entre 5, imprime \"Buzz\" en lugar del número\n- Si es divisible entre ambos, imprime \"FizzBuzz\"\n\nEjemplo de salida: 1, 2, Fizz, 4, Buzz, Fizz, 7, ...",
65
+ "expected_output": "1\n2\nFizz\n4\nBuzz\nFizz\n7\n8\nFizz\nBuzz\n11\nFizz\n13\n14\nFizzBuzz",
66
+ "time_estimate_min": 10
67
+ },
68
+ {
69
+ "id": "es-t1-factorial",
70
+ "title": "Factorial",
71
+ "tier": 1,
72
+ "prompt": "Escribe una función que calcule el factorial de un número entero positivo.\n\nEjemplos:\n- factorial(5) → 120\n- factorial(0) → 1\n- factorial(7) → 5040\n\nPista: factorial(n) = n × (n-1) × ... × 1",
73
+ "expected_output": "120\n1\n5040",
74
+ "time_estimate_min": 10
75
+ },
76
+ {
77
+ "id": "es-t1-palindrome",
78
+ "title": "Palíndromo",
79
+ "tier": 1,
80
+ "prompt": "Escribe una función que verifique si una cadena de texto es un palíndromo (se lee igual de izquierda a derecha que de derecha a izquierda).\n\nEjemplos:\n- \"reconocer\" → es palíndromo\n- \"hola\" → no es palíndromo\n- \"A man a plan a canal Panama\" → es palíndromo\n\nIgnora mayúsculas/minúsculas y espacios.",
81
+ "expected_output": "Sí\nNo\nSí",
82
+ "time_estimate_min": 15
83
+ }
84
+ ],
85
+ "tier2": [
86
+ {
87
+ "id": "es-t2-calculator",
88
+ "title": "Calculadora",
89
+ "tier": 2,
90
+ "prompt": "Escribe una calculadora de línea de comandos que soporte:\n\n- Suma, resta, multiplicación y división\n- Manejo del error de división por cero\n- Ciclo que acepta entradas hasta que el usuario escriba 'salir'\n\nFormato de entrada: \"número operador número\" (por ejemplo: \"10 + 5\")",
91
+ "expected_output": "Calculadora iniciada (escribe 'salir' para terminar)\n>>> 10 + 5 = 15",
92
+ "time_estimate_min": 25
93
+ },
94
+ {
95
+ "id": "es-t2-word-count",
96
+ "title": "Contador de palabras",
97
+ "tier": 2,
98
+ "prompt": "Escribe un programa que cuente la frecuencia de cada palabra en un texto y muestre las 10 más frecuentes ordenadas de mayor a menor.\n\nEntrada: Un texto (puede estar codificado directamente en el programa)\nSalida: Palabras y su conteo, ordenadas por frecuencia",
99
+ "expected_output": "Resultado del conteo:\n\"el\": 15 veces\n\"la\": 12 veces\n...",
100
+ "time_estimate_min": 30
101
+ }
102
+ ],
103
+ "tier3": [
104
+ {
105
+ "id": "es-t3-data-analysis",
106
+ "title": "Análisis de datos",
107
+ "tier": 3,
108
+ "prompt": "Escribe un script de análisis de datos para calificaciones de estudiantes.\n\nRequisitos:\n1. Define un conjunto de datos de al menos 10 estudiantes (nombre + calificación)\n2. Calcula el promedio, la calificación más alta y la más baja\n3. Agrupa por desempeño (Excelente 90+, Bueno 75-89, Suficiente 60-74, Insuficiente <60)\n4. Identifica estudiantes con calificación superior al promedio\n5. Genera un informe completo",
109
+ "expected_output": "Informe de calificaciones\n========================\nPromedio: 78.5\nMás alta: 98 (María García)\nMás baja: 45 (Juan López)\n...",
110
+ "time_estimate_min": 45
111
+ }
112
+ ]
113
+ },
114
+ "ur": {
115
+ "tier1": [
116
+ {
117
+ "id": "ur-t1-fizzbuzz",
118
+ "title": "فز بز",
119
+ "tier": 1,
120
+ "prompt": "ایک پروگرام لکھیں جو 1 سے 30 تک کے اعداد پرنٹ کرے۔\n\nقواعد:\n- اگر عدد 3 پر پوری طرح تقسیم ہو تو \"فز\" پرنٹ کریں\n- اگر عدد 5 پر پوری طرح تقسیم ہو تو \"بز\" پرنٹ کریں\n- اگر دونوں پر تقسیم ہو تو \"فز بز\" پرنٹ کریں\n\nمثال: 1، 2، فز، 4، بز، فز، 7، ...",
121
+ "expected_output": "1\n2\nفز\n4\nبز\nفز\n7\n8\nفز\nبز\n11\nفز\n13\n14\nفز بز",
122
+ "time_estimate_min": 10
123
+ },
124
+ {
125
+ "id": "ur-t1-factorial",
126
+ "title": "فیکٹوریل",
127
+ "tier": 1,
128
+ "prompt": "ایک فنکشن لکھیں جو کسی مثبت پورے عدد کا فیکٹوریل حساب کرے۔\n\nمثالیں:\n- فیکٹوریل(5) ← 120\n- فیکٹوریل(0) ← 1\n- فیکٹوریل(7) ← 5040\n\nیاد رہے: فیکٹوریل(ن) = ن × (ن-1) × ... × 1",
129
+ "expected_output": "120\n1\n5040",
130
+ "time_estimate_min": 10
131
+ },
132
+ {
133
+ "id": "ur-t1-palindrome",
134
+ "title": "پیلنڈروم جانچ",
135
+ "tier": 1,
136
+ "prompt": "ایک فنکشن لکھیں جو یہ بتائے کہ کوئی لفظ یا جملہ پیلنڈروم ہے یا نہیں (یعنی آگے پیچھے سے ایک جیسا پڑھا جائے)۔\n\nمثالیں:\n- \"ملم\" ← پیلنڈروم ہے\n- \"سلام\" ← پیلنڈروم نہیں\n- \"racecar\" ← پیلنڈروم ہے\n\nبڑے اور چھوٹے حروف اور خالی جگہوں کو نظرانداز کریں۔",
137
+ "expected_output": "ہاں\nنہیں\nہاں",
138
+ "time_estimate_min": 15
139
+ }
140
+ ],
141
+ "tier2": [
142
+ {
143
+ "id": "ur-t2-calculator",
144
+ "title": "حساب کتاب",
145
+ "tier": 2,
146
+ "prompt": "ایک کمانڈ لائن کیلکولیٹر لکھیں جو یہ کام کرے:\n\n- جمع، تفریق، ضرب اور تقسیم\n- صفر سے تقسیم کی غلطی کو سنبھالنا\n- لوپ جو 'خروج' لکھنے تک جاری رہے\n\nاندراج کی شکل: \"عدد آپریٹر عدد\" (مثلاً: \"10 + 5\")",
147
+ "expected_output": "کیلکولیٹر شروع ہو گیا ('خروج' لکھیں بند کرنے کے لیے)\n>>> 10 + 5 = 15",
148
+ "time_estimate_min": 25
149
+ },
150
+ {
151
+ "id": "ur-t2-word-count",
152
+ "title": "الفاظ شمار",
153
+ "tier": 2,
154
+ "prompt": "ایک پروگرام لکھیں جو کسی متن میں ہر لفظ کتنی بار آیا یہ گنے اور سب سے زیادہ استعمال ہونے والے 10 الفاظ دکھائے۔\n\nاندراج: کوئی بھی متن (پروگرام میں لکھا جا سکتا ہے)\nنتیجہ: الفاظ اور ان کی تعداد، زیادہ سے کم ترتیب میں",
155
+ "expected_output": "الفاظ شماری کا نتیجہ:\n\"کا\": 15 بار\n\"اور\": 12 بار\n...",
156
+ "time_estimate_min": 30
157
+ }
158
+ ],
159
+ "tier3": [
160
+ {
161
+ "id": "ur-t3-data-analysis",
162
+ "title": "ڈیٹا تجزیہ",
163
+ "tier": 3,
164
+ "prompt": "طلبہ کے نمبروں کے ڈیٹا کا تجزیہ کرنے والا اسکرپٹ لکھیں۔\n\nضروریات:\n1. کم از کم 10 طلبہ کا ڈیٹا تیار کریں (نام + نمبر)\n2. اوسط، سب سے زیادہ اور سب سے کم نمبر حساب کریں\n3. کارکردگی کے مطابق گروپ بنائیں (اعلیٰ 90+، اچھا 75-89، ٹھیک 60-74، کمزور <60)\n4. اوسط سے زیادہ نمبر والے طلبہ کی فہرست بنائیں\n5. مکمل رپورٹ تیار کریں",
165
+ "expected_output": "طلبہ کی کارکردگی رپورٹ\n====================\nاوسط: 78.5\nسب سے زیادہ: 98 (احمد علی)\nسب سے کم: 45 (سارہ خان)\n...",
166
+ "time_estimate_min": 45
167
+ }
168
+ ]
169
+ }
170
+ }
references/es.md ADDED
@@ -0,0 +1,291 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Spanish (Español) - Python Quick Reference
2
+
3
+ ![Legesher](https://img.shields.io/badge/Legesher-es-blue?style=for-the-badge&logo=python&logoColor=white)
4
+ ![Script](https://img.shields.io/badge/Script-Latin-green?style=for-the-badge)
5
+ ![Status](https://img.shields.io/badge/Status-Experimental-yellow?style=for-the-badge)
6
+
7
+ > Write Python code in Spanish. This guide shows the Spanish keywords
8
+ > to use for Legesher to understand your code.
9
+
10
+ ## Language Details
11
+
12
+ | Attribute | Value |
13
+ | --------- | ----- |
14
+ | **Language** | Spanish |
15
+ | **Native Name** | Español |
16
+ | **Script** | Latin |
17
+ | **ISO 639-1** | `es` |
18
+ | **ISO 639-2** | `spa` |
19
+ | **BCP 47 Tag** | `es` |
20
+ | **Text Direction** | Left-to-Right (LTR) |
21
+ | **Status** | Experimental |
22
+
23
+ ## Keywords (39 terms)
24
+
25
+ These are Python's reserved words translated to Spanish.
26
+
27
+ | English | Spanish |
28
+ | ------- | ------ |
29
+ | `and` | `y` |
30
+ | `as` | `como` |
31
+ | `assert` | `afirmar` |
32
+ | `async` | `asincrónico` |
33
+ | `await` | `esperar` |
34
+ | `break` | `romper` |
35
+ | `case` | `caso` |
36
+ | `class` | `clase` |
37
+ | `continue` | `continuar` |
38
+ | `def` | `definir` |
39
+ | `del` | `eliminar` |
40
+ | `elif` | `si_no` |
41
+ | `else` | `sino` |
42
+ | `except` | `excepto` |
43
+ | `except*` | `excepto*` |
44
+ | `False` | `falso` |
45
+ | `finally` | `finalmente` |
46
+ | `for` | `por` |
47
+ | `from` | `desde` |
48
+ | `global` | `declara_variable_global` |
49
+ | `if` | `si` |
50
+ | `import` | `importar` |
51
+ | `in` | `en` |
52
+ | `is` | `ser` |
53
+ | `lambda` | `funcion_anonima` |
54
+ | `match` | `coincidir` |
55
+ | `None` | `nulo` |
56
+ | `nonlocal` | `nolocal` |
57
+ | `not` | `no` |
58
+ | `or` | `o` |
59
+ | `pass` | `pasar` |
60
+ | `raise` | `levantar` |
61
+ | `return` | `devolver` |
62
+ | `True` | `verdadero` |
63
+ | `try` | `probar` |
64
+ | `type` | `tipo` |
65
+ | `while` | `mientras` |
66
+ | `with` | `con` |
67
+ | `yield` | `dar` |
68
+
69
+ ## Built-in Functions (72 terms)
70
+
71
+ Python's built-in functions and types in Spanish.
72
+
73
+ | English | Spanish |
74
+ | ------- | ------ |
75
+ | `abs` | `valorabsoluto` |
76
+ | `aiter` | `iterador_asincrónico` |
77
+ | `all` | `todo` |
78
+ | `anext` | `próximo` |
79
+ | `any` | `cualquier` |
80
+ | `ascii` | `asciiificar` |
81
+ | `bin` | `binario` |
82
+ | `bool` | `booleano` |
83
+ | `breakpoint` | `puntodeinterrupción` |
84
+ | `bytearray` | `conjuntoDeBytes` |
85
+ | `bytes` | `bytes_inmutables` |
86
+ | `callable` | `llamable` |
87
+ | `chr` | `carácter` |
88
+ | `classmethod` | `métododeclase` |
89
+ | `compile` | `compilar` |
90
+ | `complex` | `complejo` |
91
+ | `delattr` | `eliminar_atributo` |
92
+ | `dict` | `diccionario` |
93
+ | `dir` | `directorio` |
94
+ | `divmod` | `division_con_resta` |
95
+ | `ellipsis` | `elipsis` |
96
+ | `enumerate` | `elenumerar` |
97
+ | `eval` | `evalúo` |
98
+ | `exec` | `ejecutar` |
99
+ | `filter` | `filtrar` |
100
+ | `float` | `flotante` |
101
+ | `format` | `formatear` |
102
+ | `frozenset` | `conjuntocongelado` |
103
+ | `getattr` | `obtenerelatributo` |
104
+ | `globals` | `globales` |
105
+ | `hasattr` | `teneratributo` |
106
+ | `hash` | `resumen_hash` |
107
+ | `help` | `ayuda` |
108
+ | `hex` | `hexadecimal` |
109
+ | `id` | `identificador` |
110
+ | `input` | `entrada` |
111
+ | `int` | `entero` |
112
+ | `isinstance` | `ser_de_la_clase` |
113
+ | `issubclass` | `subclasede` |
114
+ | `iter` | `iterar` |
115
+ | `len` | `longitud` |
116
+ | `list` | `lista` |
117
+ | `locals` | `loslocales` |
118
+ | `map` | `mapear` |
119
+ | `max` | `máximo` |
120
+ | `memoryview` | `vistadememoria` |
121
+ | `min` | `minimo` |
122
+ | `next` | `siguiente` |
123
+ | `notimplemented` | `noimplementado` |
124
+ | `object` | `objeto` |
125
+ | `oct` | `octal` |
126
+ | `open` | `abrir` |
127
+ | `ord` | `ordinal` |
128
+ | `pow` | `potencia` |
129
+ | `print` | `imprimir` |
130
+ | `property` | `propiedad` |
131
+ | `range` | `rango` |
132
+ | `repr` | `representación` |
133
+ | `reversed` | `revesado` |
134
+ | `round` | `redondear` |
135
+ | `set` | `conjunto` |
136
+ | `setattr` | `asignar` |
137
+ | `slice` | `rebanada` |
138
+ | `sorted` | `ordenado` |
139
+ | `staticmethod` | `estático` |
140
+ | `str` | `cadena` |
141
+ | `sum` | `sumar` |
142
+ | `super` | `superClase` |
143
+ | `tuple` | `tupla` |
144
+ | `type` | `tipo` |
145
+ | `vars` | `variables` |
146
+ | `zip` | `acopiar` |
147
+
148
+ ## Exceptions (69 terms)
149
+
150
+ Exception classes for error handling.
151
+
152
+ | English | Spanish |
153
+ | ------- | ------ |
154
+ | `arithmeticerror` | `erroraritmético` |
155
+ | `assertionerror` | `errordeaserción` |
156
+ | `attributeerror` | `Errordeatributo` |
157
+ | `baseexception` | `excepciónbase` |
158
+ | `baseexceptiongroup` | `grupodeexcepcionesbase` |
159
+ | `basegeneratorexit` | `generarsalida` |
160
+ | `blockingioerror` | `errordeESbloqueante` |
161
+ | `brokenpipeerror` | `errordetuberíarota` |
162
+ | `buffererror` | `errordebúfer` |
163
+ | `byteswarning` | `advertenciadebytes` |
164
+ | `childprocesserror` | `errordeprocesosecundario` |
165
+ | `connectionabortederror` | `errordeabortarconexión` |
166
+ | `connectionerror` | `errordeconexión` |
167
+ | `connectionrefusederror` | `errorderechazodeconexión` |
168
+ | `connectionreseterror` | `resetearconexión` |
169
+ | `deprecationwarning` | `advertenciadedepreciación` |
170
+ | `encodingwarning` | `advertenciadecodificación` |
171
+ | `environmenterror` | `errordeentorno` |
172
+ | `eoferror` | `errordeentradasalida` |
173
+ | `exception` | `excepción` |
174
+ | `exceptiongroup` | `grupodeexcepciones` |
175
+ | `fileexistserror` | `errordeexistenciadearchivo` |
176
+ | `filenotfounderror` | `Errordenoencontrarelarchivo` |
177
+ | `floatingpointerror` | `errordepunteroflotante` |
178
+ | `futurewarning` | `advertenciafutura` |
179
+ | `generatorexit` | `salidadegenerador` |
180
+ | `importerror` | `errordeimportación` |
181
+ | `importwarning` | `advertenciadeimportación` |
182
+ | `indentationerror` | `errordesangría` |
183
+ | `indexerror` | `Errordeíndice` |
184
+ | `interruptederror` | `errordeinterrupción` |
185
+ | `ioerror` | `errordeES` |
186
+ | `isadirectoryerror` | `errordedirectorio` |
187
+ | `keyboardinterrupt` | `interrupcióndelteclado` |
188
+ | `keyerror` | `errordeclave` |
189
+ | `lookuperror` | `errordebúsqueda` |
190
+ | `memoryerror` | `errordememoria` |
191
+ | `modulenotfounderror` | `Errordemódulonoencontrado` |
192
+ | `nameerror` | `Errordenombre` |
193
+ | `notadirectoryerror` | `errordenoserundirectorio` |
194
+ | `notimplementederror` | `errordenoimplementación` |
195
+ | `oserror` | `ErrorDeOS` |
196
+ | `overflowerror` | `errordedesbordamiento` |
197
+ | `pendingdeprecationwarning` | `advertenciadeadvertenciadedepreciaciónpendiente` |
198
+ | `permissionerror` | `errordepermiso` |
199
+ | `processlookuperror` | `errordebúsquedadeproceso` |
200
+ | `recursionerror` | `errorderecursión` |
201
+ | `referenceerror` | `errordereferencia` |
202
+ | `resourcewarning` | `advertenciaderecursos` |
203
+ | `runtimeerror` | `errorentiempodeejecución` |
204
+ | `runtimewarning` | `advertenciadetiempodeejecución` |
205
+ | `stopasynciteration` | `detenerlaiteraciónasincrónica` |
206
+ | `stopiteration` | `detener_iteración` |
207
+ | `syntaxerror` | `errordesintaxis` |
208
+ | `syntaxwarning` | `advertenciadesintaxis` |
209
+ | `systemexit` | `salirdelsistema` |
210
+ | `taberror` | `errordetabulación` |
211
+ | `timeouterror` | `errordetiempodeespera` |
212
+ | `typeerror` | `errordetipo` |
213
+ | `unboundlocalerror` | `errordereferencialocalnoenlazada` |
214
+ | `unicodedecodeerror` | `errordedecodificacióndeUnicode` |
215
+ | `unicodeencodeerror` | `errordecodificaciónunicode` |
216
+ | `unicodeerror` | `errordeunicode` |
217
+ | `unicodetranslateerror` | `errordetraduccióndeUnicode` |
218
+ | `unicodewarning` | `advertenciadeunicode` |
219
+ | `userwarning` | `advertenciadelusuario` |
220
+ | `valueerror` | `errordevalor` |
221
+ | `warning` | `advertencia` |
222
+ | `zerodivisionerror` | `errordedivisiónporcero` |
223
+
224
+ ## Example Code
225
+
226
+ Here's an example showing Spanish Python code with Legesher:
227
+
228
+ ```python
229
+ # Ejemplo: Función factorial con manejo de errores
230
+
231
+ desde typing importar Optional
232
+
233
+ definir factorial(n):
234
+ """Calcular el factorial de n."""
235
+ si n < 0:
236
+ levantar Errordevalor("Los números negativos no están permitidos")
237
+ si_no n == 0 o n == 1:
238
+ devolver 1
239
+ sino:
240
+ devolver n * factorial(n - 1)
241
+
242
+ definir principal():
243
+ numeros = [entero(x) por x en rango(6)]
244
+
245
+ por numero en numeros:
246
+ resultado = factorial(numero)
247
+ imprimir(f"{numero}! = {resultado}")
248
+
249
+ # Demostrar bucle while
250
+ contador = 0
251
+ mientras contador < 3:
252
+ imprimir(f"Contador: {contador}")
253
+ contador += 1
254
+
255
+ # Demostrar try/except
256
+ probar:
257
+ factorial(-1)
258
+ excepto Errordevalor como error:
259
+ imprimir(f"Error: {error}")
260
+ finalmente:
261
+ imprimir("¡Listo!")
262
+
263
+ si __name__ == "__main__":
264
+ principal()
265
+ ```
266
+
267
+ ## Usage
268
+
269
+ ```python
270
+ from legesher_i18n import LanguagePackLoader
271
+
272
+ # Load Spanish pack for Python 3.12
273
+ loader = LanguagePackLoader()
274
+ pack = loader.load("es", "python", "3.12")
275
+
276
+ # Translate code
277
+ from legesher import translate
278
+ english_code = translate(your_es_code, from_lang="es", to_lang="en")
279
+ ```
280
+
281
+ ## Contributing
282
+
283
+ Found a better translation? We welcome contributions from native speakers!
284
+
285
+ 1. Edit `legesher_i18n_python_es/packs/<version>.yml` for the Python version where the term was introduced:
286
+ - `3.10.yml` - Base translations (most terms)
287
+ - `3.11.yml` - Terms added in Python 3.11 (e.g., `except*`)
288
+ - `3.12.yml` - Terms added in Python 3.12 (e.g., `type`)
289
+ - `3.13.yml` / `3.14.yml` - Future additions
290
+ 2. Submit a pull request with your reasoning
291
+ 3. Translations should be natural, commonly used in CS education, and easy to type
references/ur.md ADDED
@@ -0,0 +1,294 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Urdu (اردو) - Python Quick Reference
2
+
3
+ ![Legesher](https://img.shields.io/badge/Legesher-ur-blue?style=for-the-badge&logo=python&logoColor=white)
4
+ ![Script](https://img.shields.io/badge/Script-Arabic-green?style=for-the-badge)
5
+ ![Status](https://img.shields.io/badge/Status-Experimental-yellow?style=for-the-badge)
6
+ ![RTL](https://img.shields.io/badge/Direction-RTL-orange?style=for-the-badge)
7
+
8
+ > Write Python code in Urdu. This guide shows the Urdu keywords
9
+ > to use for Legesher to understand your code.
10
+ >
11
+ > **Note:** This is a right-to-left (RTL) language. RTL support is currently a work in progress — we welcome your feedback!
12
+
13
+ ## Language Details
14
+
15
+ | Attribute | Value |
16
+ | --------- | ----- |
17
+ | **Language** | Urdu |
18
+ | **Native Name** | اردو |
19
+ | **Script** | Arabic |
20
+ | **ISO 639-1** | `ur` |
21
+ | **ISO 639-2** | `urd` |
22
+ | **BCP 47 Tag** | `ur` |
23
+ | **Text Direction** | Right-to-Left (RTL) |
24
+ | **Status** | Experimental |
25
+
26
+ ## Keywords (39 terms)
27
+
28
+ These are Python's reserved words translated to Urdu.
29
+
30
+ | English | Urdu |
31
+ | ------- | ------ |
32
+ | `and` | `اور` |
33
+ | `as` | `بطور` |
34
+ | `assert` | `تصدیق` |
35
+ | `async` | `غیرہمزمان` |
36
+ | `await` | `انتظار` |
37
+ | `break` | `توڑ` |
38
+ | `case` | `صورت` |
39
+ | `class` | `جماعت` |
40
+ | `continue` | `جاری` |
41
+ | `def` | `تعریف` |
42
+ | `del` | `مٹاؤ` |
43
+ | `elif` | `ورنہاگر` |
44
+ | `else` | `ورنہ` |
45
+ | `except` | `سوائے` |
46
+ | `except*` | `سوائے*` |
47
+ | `False` | `غلط` |
48
+ | `finally` | `بالآخر` |
49
+ | `for` | `لیے` |
50
+ | `from` | `سے` |
51
+ | `global` | `عالمی` |
52
+ | `if` | `اگر` |
53
+ | `import` | `درآمد` |
54
+ | `in` | `میں` |
55
+ | `is` | `ہے` |
56
+ | `lambda` | `لیمڈا` |
57
+ | `match` | `مماثلت` |
58
+ | `None` | `کچھنہیں` |
59
+ | `nonlocal` | `غیرمقامی` |
60
+ | `not` | `نہیں` |
61
+ | `or` | `یا` |
62
+ | `pass` | `گزر` |
63
+ | `raise` | `اٹھاؤ` |
64
+ | `return` | `واپسی` |
65
+ | `True` | `صحیح` |
66
+ | `try` | `کوشش` |
67
+ | `type` | `نوعیت` |
68
+ | `while` | `جبتک` |
69
+ | `with` | `ساتھ` |
70
+ | `yield` | `حاصل` |
71
+
72
+ ## Built-in Functions (72 terms)
73
+
74
+ Python's built-in functions and types in Urdu.
75
+
76
+ | English | Urdu |
77
+ | ------- | ------ |
78
+ | `abs` | `مطلق` |
79
+ | `aiter` | `غیرہمزمانتکرارکنندہ` |
80
+ | `all` | `تمام` |
81
+ | `anext` | `غیرہمزماناگلا` |
82
+ | `any` | `کوئی` |
83
+ | `ascii` | `آسکی` |
84
+ | `bin` | `ثنائی` |
85
+ | `bool` | `منطقی` |
86
+ | `breakpoint` | `وقفہ` |
87
+ | `bytearray` | `بائٹصف` |
88
+ | `bytes` | `بائٹس` |
89
+ | `callable` | `قابلِاستعمال` |
90
+ | `chr` | `حرف` |
91
+ | `classmethod` | `جماعتطریقہ` |
92
+ | `compile` | `تالیف` |
93
+ | `complex` | `مرکب` |
94
+ | `delattr` | `خاصیت_مٹاؤ` |
95
+ | `dict` | `لغت` |
96
+ | `dir` | `فہرست` |
97
+ | `divmod` | `تقسیمباقی` |
98
+ | `ellipsis` | `حذف` |
99
+ | `enumerate` | `شمار` |
100
+ | `eval` | `جانچ` |
101
+ | `exec` | `عمل` |
102
+ | `filter` | `چھاننا` |
103
+ | `float` | `اعشاری` |
104
+ | `format` | `شکل` |
105
+ | `frozenset` | `منجمدمجموعہ` |
106
+ | `getattr` | `خاصیت_لاؤ` |
107
+ | `globals` | `عالمیمتغیرات` |
108
+ | `hasattr` | `خاصیت_ہے` |
109
+ | `hash` | `ہیش` |
110
+ | `help` | `مدد` |
111
+ | `hex` | `سداسی` |
112
+ | `id` | `شناخت` |
113
+ | `input` | `داخلہ` |
114
+ | `int` | `عددصحیح` |
115
+ | `isinstance` | `مثال_ہے` |
116
+ | `issubclass` | `ذیلی_جماعت_ہے` |
117
+ | `iter` | `تکرارکنندہ` |
118
+ | `len` | `لمبائی` |
119
+ | `list` | `فہرستی` |
120
+ | `locals` | `مقامیمتغیرات` |
121
+ | `map` | `نقشہ` |
122
+ | `max` | `زیادہ` |
123
+ | `memoryview` | `یادداشتنظارہ` |
124
+ | `min` | `کمترین` |
125
+ | `next` | `اگلا` |
126
+ | `notimplemented` | `غیرنافذ` |
127
+ | `object` | `شے` |
128
+ | `oct` | `ہشتی` |
129
+ | `open` | `کھولو` |
130
+ | `ord` | `ترتیب` |
131
+ | `pow` | `قوت` |
132
+ | `print` | `چھاپو` |
133
+ | `property` | `خاصیت` |
134
+ | `range` | `حدود` |
135
+ | `repr` | `نمائندگی` |
136
+ | `reversed` | `الٹا` |
137
+ | `round` | `گول` |
138
+ | `set` | `مجموعہ` |
139
+ | `setattr` | `خاصیت_مقرر` |
140
+ | `slice` | `ٹکڑا` |
141
+ | `sorted` | `ترتیبشدہ` |
142
+ | `staticmethod` | `جامدطریقہ` |
143
+ | `str` | `متن` |
144
+ | `sum` | `کل` |
145
+ | `super` | `بالائی` |
146
+ | `tuple` | `ٹپل` |
147
+ | `type` | `نوعیت` |
148
+ | `vars` | `متغیرات_لاؤ` |
149
+ | `zip` | `جوڑا` |
150
+
151
+ ## Exceptions (69 terms)
152
+
153
+ Exception classes for error handling.
154
+
155
+ | English | Urdu |
156
+ | ------- | ------ |
157
+ | `arithmeticerror` | `حسابیغلطی` |
158
+ | `assertionerror` | `تصدیقغلطی` |
159
+ | `attributeerror` | `خاصیتغلطی` |
160
+ | `baseexception` | `بنیادیاستثنا` |
161
+ | `baseexceptiongroup` | `بنیادیاستثناگروہ` |
162
+ | `basegeneratorexit` | `بنیادیجنریٹرخروج` |
163
+ | `blockingioerror` | `مسدودداخلہخارجہغلطی` |
164
+ | `brokenpipeerror` | `ٹوٹاپائپغلطی` |
165
+ | `buffererror` | `بفرغلطی` |
166
+ | `byteswarning` | `بائٹسانتباہ` |
167
+ | `childprocesserror` | `ذیلیعملغلطی` |
168
+ | `connectionabortederror` | `رابطہمنسوخغلطی` |
169
+ | `connectionerror` | `رابطہغلطی` |
170
+ | `connectionrefusederror` | `رابطہمستردغلطی` |
171
+ | `connectionreseterror` | `رابطہدوبارہغلطی` |
172
+ | `deprecationwarning` | `متروکانتباہ` |
173
+ | `encodingwarning` | `ضابطہبندیانتباہ` |
174
+ | `environmenterror` | `ماحولغلطی` |
175
+ | `eoferror` | `فائلختمغلطی` |
176
+ | `exception` | `استثنا` |
177
+ | `exceptiongroup` | `استثناگروہ` |
178
+ | `fileexistserror` | `فائلموجودغلطی` |
179
+ | `filenotfounderror` | `فائلنہملیغلطی` |
180
+ | `floatingpointerror` | `اعشاریاشارہغلطی` |
181
+ | `futurewarning` | `مستقبلانتباہ` |
182
+ | `generatorexit` | `جنریٹرخروج` |
183
+ | `importerror` | `درآمدغلطی` |
184
+ | `importwarning` | `درآمدانتباہ` |
185
+ | `indentationerror` | `حاشیہغلطی` |
186
+ | `indexerror` | `اشاریہغلطی` |
187
+ | `interruptederror` | `رکاوٹغلطی` |
188
+ | `ioerror` | `داخلہخارجہغلطی` |
189
+ | `isadirectoryerror` | `ڈائریکٹریہےغلطی` |
190
+ | `keyboardinterrupt` | `کلیدتختہرکاوٹ` |
191
+ | `keyerror` | `کلیدغلطی` |
192
+ | `lookuperror` | `تلاشغلطی` |
193
+ | `memoryerror` | `یادداشتغلطی` |
194
+ | `modulenotfounderror` | `ماڈیولنہملاغلطی` |
195
+ | `nameerror` | `نامغلطی` |
196
+ | `notadirectoryerror` | `ڈائریکٹرینہیںغلطی` |
197
+ | `notimplementederror` | `غیرنافذغلطی` |
198
+ | `oserror` | `آپریٹنگنظامغلطی` |
199
+ | `overflowerror` | `اوورفلوغلطی` |
200
+ | `pendingdeprecationwarning` | `زیرالتواءمتروکانتباہ` |
201
+ | `permissionerror` | `اجازتغلطی` |
202
+ | `processlookuperror` | `عملتلاشغلطی` |
203
+ | `recursionerror` | `تکرارغلطی` |
204
+ | `referenceerror` | `حوالہغلطی` |
205
+ | `resourcewarning` | `وسائلانتباہ` |
206
+ | `runtimeerror` | `وقتعملغلطی` |
207
+ | `runtimewarning` | `وقتعملانتباہ` |
208
+ | `stopasynciteration` | `غیرہمزمانتکراررُک` |
209
+ | `stopiteration` | `تکراررُک` |
210
+ | `syntaxerror` | `نحوغلطی` |
211
+ | `syntaxwarning` | `نحوانتباہ` |
212
+ | `systemexit` | `نظامخروج` |
213
+ | `taberror` | `ٹیبغلطی` |
214
+ | `timeouterror` | `وقتختمغلطی` |
215
+ | `typeerror` | `قسم_غلطی` |
216
+ | `unboundlocalerror` | `غیرمربوطمقامیغلطی` |
217
+ | `unicodedecodeerror` | `یونیکوڈضابطہکشائیغلطی` |
218
+ | `unicodeencodeerror` | `یونیکوڈضابطہبندیغلطی` |
219
+ | `unicodeerror` | `یونیکوڈغلطی` |
220
+ | `unicodetranslateerror` | `یونیکوڈترجمہغلطی` |
221
+ | `unicodewarning` | `یونیکوڈانتباہ` |
222
+ | `userwarning` | `صارفاطلاع` |
223
+ | `valueerror` | `قدرغلطی` |
224
+ | `warning` | `انتباہ` |
225
+ | `zerodivisionerror` | `صفرتقسیمغلطی` |
226
+
227
+ ## Example Code
228
+
229
+ Here's an example showing Urdu Python code with Legesher:
230
+
231
+ ```python
232
+ # مثال: غلطی کی ہینڈلنگ کے ساتھ فیکٹوریل فنکشن
233
+
234
+ سے typing درآمد Optional
235
+
236
+ تعریف فیکٹوریل(n):
237
+ """عدد ن کا فیکٹوریل حساب کریں۔"""
238
+ اگر n < 0:
239
+ اٹھاؤ قدرغلطی("منفی اعداد کی اجازت نہیں")
240
+ ورنہاگر n == 0 یا n == 1:
241
+ واپسی 1
242
+ ورنہ:
243
+ واپسی n * فیکٹوریل(n - 1)
244
+
245
+ تعریف مرکزی():
246
+ اعداد = [عددصحیح(x) لیے x میں حدود(6)]
247
+
248
+ لیے عدد میں اعداد:
249
+ نتیجہ = فیکٹوریل(عدد)
250
+ چھاپو(f"{عدد}! = {نتیجہ}")
251
+
252
+ # جبتک لوپ کا مظاہرہ
253
+ گنتی = 0
254
+ جبتک گنتی < 3:
255
+ چھاپو(f"گنتی: {گنتی}")
256
+ گنتی += 1
257
+
258
+ # کوشش/سوائے کا مظاہرہ
259
+ کوشش:
260
+ فیکٹوریل(-1)
261
+ سوائے قدرغلطی بطور غلطی:
262
+ چھاپو(f"غلطی: {غلطی}")
263
+ بالآخر:
264
+ چھاپو("مکمل!")
265
+
266
+ اگر __name__ == "__main__":
267
+ مرکزی()
268
+ ```
269
+
270
+ ## Usage
271
+
272
+ ```python
273
+ from legesher_i18n import LanguagePackLoader
274
+
275
+ # Load Urdu pack for Python 3.12
276
+ loader = LanguagePackLoader()
277
+ pack = loader.load("ur", "python", "3.12")
278
+
279
+ # Translate code
280
+ from legesher import translate
281
+ english_code = translate(your_ur_code, from_lang="ur", to_lang="en")
282
+ ```
283
+
284
+ ## Contributing
285
+
286
+ Found a better translation? We welcome contributions from native speakers!
287
+
288
+ 1. Edit `legesher_i18n_python_ur/packs/<version>.yml` for the Python version where the term was introduced:
289
+ - `3.10.yml` - Base translations (most terms)
290
+ - `3.11.yml` - Terms added in Python 3.11 (e.g., `except*`)
291
+ - `3.12.yml` - Terms added in Python 3.12 (e.g., `type`)
292
+ - `3.13.yml` / `3.14.yml` - Future additions
293
+ 2. Submit a pull request with your reasoning
294
+ 3. Translations should be natural, commonly used in CS education, and easy to type
references/zh.md ADDED
@@ -0,0 +1,291 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Chinese (中文) - Python Quick Reference
2
+
3
+ ![Legesher](https://img.shields.io/badge/Legesher-zh-blue?style=for-the-badge&logo=python&logoColor=white)
4
+ ![Script](https://img.shields.io/badge/Script-Simplified%20Chinese%20%28Han%29-green?style=for-the-badge)
5
+ ![Status](https://img.shields.io/badge/Status-Experimental-yellow?style=for-the-badge)
6
+
7
+ > Write Python code in Chinese. This guide shows the Chinese keywords
8
+ > to use for Legesher to understand your code.
9
+
10
+ ## Language Details
11
+
12
+ | Attribute | Value |
13
+ | --------- | ----- |
14
+ | **Language** | Chinese |
15
+ | **Native Name** | 中文 |
16
+ | **Script** | Simplified Chinese (Han) |
17
+ | **ISO 639-1** | `zh` |
18
+ | **ISO 639-2** | `zho` |
19
+ | **BCP 47 Tag** | `zh-Hans` |
20
+ | **Text Direction** | Left-to-Right (LTR) |
21
+ | **Status** | Experimental |
22
+
23
+ ## Keywords (39 terms)
24
+
25
+ These are Python's reserved words translated to Chinese.
26
+
27
+ | English | Chinese |
28
+ | ------- | ------ |
29
+ | `and` | `和` |
30
+ | `as` | `作为` |
31
+ | `assert` | `断言` |
32
+ | `async` | `异步` |
33
+ | `await` | `等待` |
34
+ | `break` | `终止` |
35
+ | `case` | `情况` |
36
+ | `class` | `类` |
37
+ | `continue` | `继续` |
38
+ | `def` | `定义` |
39
+ | `del` | `删除` |
40
+ | `elif` | `否则如果` |
41
+ | `else` | `否则` |
42
+ | `except` | `除外` |
43
+ | `except*` | `多重捕获*` |
44
+ | `False` | `错误` |
45
+ | `finally` | `最后` |
46
+ | `for` | `对于` |
47
+ | `from` | `从` |
48
+ | `global` | `全球` |
49
+ | `if` | `如果` |
50
+ | `import` | `导入` |
51
+ | `in` | `在` |
52
+ | `is` | `是` |
53
+ | `lambda` | `拉姆达` |
54
+ | `match` | `匹配` |
55
+ | `None` | `无` |
56
+ | `nonlocal` | `非本地` |
57
+ | `not` | `不` |
58
+ | `or` | `或` |
59
+ | `pass` | `过` |
60
+ | `raise` | `提出` |
61
+ | `return` | `返回` |
62
+ | `True` | `真实` |
63
+ | `try` | `尝试` |
64
+ | `type` | `类型` |
65
+ | `while` | `当` |
66
+ | `with` | `跟` |
67
+ | `yield` | `产生` |
68
+
69
+ ## Built-in Functions (72 terms)
70
+
71
+ Python's built-in functions and types in Chinese.
72
+
73
+ | English | Chinese |
74
+ | ------- | ------ |
75
+ | `abs` | `绝对值` |
76
+ | `aiter` | `异步迭代器` |
77
+ | `all` | `全` |
78
+ | `anext` | `下一项` |
79
+ | `any` | `任意` |
80
+ | `ascii` | `ASCII` |
81
+ | `bin` | `二进制` |
82
+ | `bool` | `布尔` |
83
+ | `breakpoint` | `断点` |
84
+ | `bytearray` | `字节数组` |
85
+ | `bytes` | `字节` |
86
+ | `callable` | `可调用` |
87
+ | `chr` | `字符` |
88
+ | `classmethod` | `类方法` |
89
+ | `compile` | `编译` |
90
+ | `complex` | `复数` |
91
+ | `delattr` | `删除属性` |
92
+ | `dict` | `字典` |
93
+ | `dir` | `列出属性和方法` |
94
+ | `divmod` | `除模` |
95
+ | `ellipsis` | `省略号` |
96
+ | `enumerate` | `枚举` |
97
+ | `eval` | `评估` |
98
+ | `exec` | `执行` |
99
+ | `filter` | `过滤` |
100
+ | `float` | `浮点数` |
101
+ | `format` | `格式化` |
102
+ | `frozenset` | `冻结集` |
103
+ | `getattr` | `获取属性` |
104
+ | `globals` | `全局变量` |
105
+ | `hasattr` | `具有` |
106
+ | `hash` | `哈希` |
107
+ | `help` | `帮助` |
108
+ | `hex` | `十六进制` |
109
+ | `id` | `标识` |
110
+ | `input` | `输入` |
111
+ | `int` | `整数` |
112
+ | `isinstance` | `是实例` |
113
+ | `issubclass` | `是子类` |
114
+ | `iter` | `迭代` |
115
+ | `len` | `长度` |
116
+ | `list` | `列表` |
117
+ | `locals` | `局部变量` |
118
+ | `map` | `映射` |
119
+ | `max` | `最大值` |
120
+ | `memoryview` | `内存视图` |
121
+ | `min` | `最小值` |
122
+ | `next` | `下一个` |
123
+ | `notimplemented` | `未实现` |
124
+ | `object` | `对象` |
125
+ | `oct` | `八进制` |
126
+ | `open` | `打开` |
127
+ | `ord` | `顺序` |
128
+ | `pow` | `幂` |
129
+ | `print` | `打印` |
130
+ | `property` | `属性` |
131
+ | `range` | `范围` |
132
+ | `repr` | `表示` |
133
+ | `reversed` | `反转` |
134
+ | `round` | `四舍五入` |
135
+ | `set` | `集合` |
136
+ | `setattr` | `设置属性` |
137
+ | `slice` | `切片` |
138
+ | `sorted` | `排序` |
139
+ | `staticmethod` | `静态方法` |
140
+ | `str` | `字符串` |
141
+ | `sum` | `求和` |
142
+ | `super` | `超类` |
143
+ | `tuple` | `元组` |
144
+ | `type` | `类型` |
145
+ | `vars` | `变量字典` |
146
+ | `zip` | `压缩` |
147
+
148
+ ## Exceptions (69 terms)
149
+
150
+ Exception classes for error handling.
151
+
152
+ | English | Chinese |
153
+ | ------- | ------ |
154
+ | `arithmeticerror` | `算术错误` |
155
+ | `assertionerror` | `断言错误` |
156
+ | `attributeerror` | `属性错误` |
157
+ | `baseexception` | `基本异常` |
158
+ | `baseexceptiongroup` | `基异常组` |
159
+ | `basegeneratorexit` | `基底生成器退出` |
160
+ | `blockingioerror` | `阻塞的IO错误` |
161
+ | `brokenpipeerror` | `破管错误` |
162
+ | `buffererror` | `缓冲区错误` |
163
+ | `byteswarning` | `字节警告` |
164
+ | `childprocesserror` | `子进程错误` |
165
+ | `connectionabortederror` | `连接中断错误` |
166
+ | `connectionerror` | `连接错误` |
167
+ | `connectionrefusederror` | `连接拒绝错误` |
168
+ | `connectionreseterror` | `连接重置错误` |
169
+ | `deprecationwarning` | `弃用警告` |
170
+ | `encodingwarning` | `编码警告` |
171
+ | `environmenterror` | `环境错误` |
172
+ | `eoferror` | `文件结束错误` |
173
+ | `exception` | `异常` |
174
+ | `exceptiongroup` | `异常组` |
175
+ | `fileexistserror` | `文件已存在错误` |
176
+ | `filenotfounderror` | `文件未找到错误` |
177
+ | `floatingpointerror` | `浮点数错误` |
178
+ | `futurewarning` | `未来警告` |
179
+ | `generatorexit` | `生成器退出` |
180
+ | `importerror` | `导入错误` |
181
+ | `importwarning` | `导入警告` |
182
+ | `indentationerror` | `缩进错误` |
183
+ | `indexerror` | `越界访问错误` |
184
+ | `interruptederror` | `中断错误` |
185
+ | `ioerror` | `IO错误` |
186
+ | `isadirectoryerror` | `是目录错误` |
187
+ | `keyboardinterrupt` | `键盘中断` |
188
+ | `keyerror` | `键错误` |
189
+ | `lookuperror` | `查找错误` |
190
+ | `memoryerror` | `内存错误` |
191
+ | `modulenotfounderror` | `模块未找到错误` |
192
+ | `nameerror` | `名称错误` |
193
+ | `notadirectoryerror` | `非目录错误` |
194
+ | `notimplementederror` | `未实现错误` |
195
+ | `oserror` | `操作系统错误` |
196
+ | `overflowerror` | `溢出错误` |
197
+ | `pendingdeprecationwarning` | `待删除警告` |
198
+ | `permissionerror` | `权限错误` |
199
+ | `processlookuperror` | `进程查找错误` |
200
+ | `recursionerror` | `递归错误` |
201
+ | `referenceerror` | `引用错误` |
202
+ | `resourcewarning` | `资源警告` |
203
+ | `runtimeerror` | `运行时错误` |
204
+ | `runtimewarning` | `运行时警告` |
205
+ | `stopasynciteration` | `停止异步迭代` |
206
+ | `stopiteration` | `停止迭代` |
207
+ | `syntaxerror` | `语法错误` |
208
+ | `syntaxwarning` | `语法警告` |
209
+ | `systemexit` | `系统退出` |
210
+ | `taberror` | `制表符错误` |
211
+ | `timeouterror` | `超时错误` |
212
+ | `typeerror` | `类型错误` |
213
+ | `unboundlocalerror` | `未绑定局部错误` |
214
+ | `unicodedecodeerror` | `统一码解码错误` |
215
+ | `unicodeencodeerror` | `统一码编码错误` |
216
+ | `unicodeerror` | `统一码错误` |
217
+ | `unicodetranslateerror` | `统一码转换错误` |
218
+ | `unicodewarning` | `统一码警告` |
219
+ | `userwarning` | `用户警告` |
220
+ | `valueerror` | `值错误` |
221
+ | `warning` | `警告` |
222
+ | `zerodivisionerror` | `零除数错误` |
223
+
224
+ ## Example Code
225
+
226
+ Here's an example showing Chinese Python code with Legesher:
227
+
228
+ ```python
229
+ # 示例:带错误处理的阶乘函数
230
+
231
+ 从 typing 导入 Optional
232
+
233
+ 定义 阶乘(n):
234
+ """计算n的阶乘。"""
235
+ 如果 n < 0:
236
+ 提出 值错误("不允许负数")
237
+ 否则如果 n == 0 或 n == 1:
238
+ 返回 1
239
+ 否则:
240
+ 返回 n * 阶乘(n - 1)
241
+
242
+ 定义 主函数():
243
+ 数字列表 = [整数(x) 对于 x 在 范围(6)]
244
+
245
+ 对于 数字 在 数字列表:
246
+ 结果 = 阶乘(数字)
247
+ 打印(f"{数字}! = {结果}")
248
+
249
+ # 演示while循环
250
+ 计数 = 0
251
+ 当 计数 < 3:
252
+ 打印(f"计数: {计数}")
253
+ 计数 += 1
254
+
255
+ # 演示try/except
256
+ 尝试:
257
+ 阶乘(-1)
258
+ 除外 值错误 作为 错误:
259
+ 打印(f"错误: {错误}")
260
+ 最后:
261
+ 打印("完成!")
262
+
263
+ 如果 __name__ == "__main__":
264
+ 主函数()
265
+ ```
266
+
267
+ ## Usage
268
+
269
+ ```python
270
+ from legesher_i18n import LanguagePackLoader
271
+
272
+ # Load Chinese pack for Python 3.12
273
+ loader = LanguagePackLoader()
274
+ pack = loader.load("zh", "python", "3.12")
275
+
276
+ # Translate code
277
+ from legesher import translate
278
+ english_code = translate(your_zh_code, from_lang="zh", to_lang="en")
279
+ ```
280
+
281
+ ## Contributing
282
+
283
+ Found a better translation? We welcome contributions from native speakers!
284
+
285
+ 1. Edit `legesher_i18n_python_zh/packs/<version>.yml` for the Python version where the term was introduced:
286
+ - `3.10.yml` - Base translations (most terms)
287
+ - `3.11.yml` - Terms added in Python 3.11 (e.g., `except*`)
288
+ - `3.12.yml` - Terms added in Python 3.12 (e.g., `type`)
289
+ - `3.13.yml` / `3.14.yml` - Future additions
290
+ 2. Submit a pull request with your reasoning
291
+ 3. Translations should be natural, commonly used in CS education, and easy to type
requirements.txt ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ gradio>=4.44.0
2
+ huggingface_hub>=0.24.0
3
+ datasets>=2.20.0
4
+ tree-sitter>=0.20.4
5
+ tree-sitter-python>=0.21.0
6
+
7
+ # Legesher packages (bundled in wheels/)
8
+ ./wheels/legesher_core-0.7.3-py3-none-any.whl
9
+ ./wheels/legesher_i18n-0.7.3-py3-none-any.whl
10
+ ./wheels/legesher-0.7.3-py3-none-any.whl
11
+ ./wheels/legesher_i18n_python_en-0.0.2-py3-none-any.whl
12
+ ./wheels/legesher_i18n_python_zh-0.0.4-py3-none-any.whl
13
+ ./wheels/legesher_i18n_python_es-0.0.3-py3-none-any.whl
14
+ ./wheels/legesher_i18n_python_ur-0.0.2-py3-none-any.whl
wheels/legesher-0.7.3-py3-none-any.whl ADDED
Binary file (40 kB). View file
 
wheels/legesher_core-0.7.3-py3-none-any.whl ADDED
Binary file (65.9 kB). View file
 
wheels/legesher_i18n-0.7.3-py3-none-any.whl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:227588a0e1ce7a3ba9a049a8999debb18b214b70c1027ebb4f060ae6ac11f0c5
3
+ size 1854709
wheels/legesher_i18n_python_en-0.0.2-py3-none-any.whl ADDED
Binary file (6.67 kB). View file
 
wheels/legesher_i18n_python_es-0.0.3-py3-none-any.whl ADDED
Binary file (6.64 kB). View file
 
wheels/legesher_i18n_python_ur-0.0.2-py3-none-any.whl ADDED
Binary file (7.17 kB). View file
 
wheels/legesher_i18n_python_zh-0.0.4-py3-none-any.whl ADDED
Binary file (6.95 kB). View file