日语五十音练习
代码由DS生成。
这是一个日语五十音练习程序。用户可自选练习范围(按行或星标词),支持四种题型:罗马音→假名、平假名→片假名+罗马音、片假名→平假名+罗马音、任意假名→罗马音+另一假名。用户自评后错题自动记录,可重测本次错题;错题本支持专项练习(连续答对两次移除)。提供考试模式(自定义题数,自评计分),星标管理模块可添加/移除星标词并作为考试范围。所有功能集成于主菜单,交互友好。
import random # ========== 完整五十音数据 ========== # 罗马音 -> (平假名, 片假名) kana_dict = { "a": ("あ", "ア"), "i": ("い", "イ"), "u": ("う", "ウ"), "e": ("え", "エ"), "o": ("お", "オ"), "ka": ("か", "カ"), "ki": ("き", "キ"), "ku": ("く", "ク"), "ke": ("け", "ケ"), "ko": ("こ", "コ"), "sa": ("さ", "サ"), "shi": ("し", "シ"), "su": ("す", "ス"), "se": ("せ", "セ"), "so": ("そ", "ソ"), "ta": ("た", "タ"), "chi": ("ち", "チ"), "tsu": ("つ", "ツ"), "te": ("て", "テ"), "to": ("と", "ト"), "na": ("な", "ナ"), "ni": ("に", "ニ"), "nu": ("ぬ", "ヌ"), "ne": ("ね", "ネ"), "no": ("の", "ノ"), "ha": ("は", "ハ"), "hi": ("ひ", "ヒ"), "fu": ("ふ", "フ"), "he": ("へ", "ヘ"), "ho": ("ほ", "ホ"), "ma": ("ま", "マ"), "mi": ("み", "ミ"), "mu": ("む", "ム"), "me": ("め", "メ"), "mo": ("も", "モ"), "ya": ("や", "ヤ"), "yu": ("ゆ", "ユ"), "yo": ("よ", "ヨ"), "ra": ("ら", "ラ"), "ri": ("り", "リ"), "ru": ("る", "ル"), "re": ("れ", "レ"), "ro": ("ろ", "ロ"), "wa": ("わ", "ワ"), "wo": ("を", "ヲ"), "n": ("ん", "ン"), "ga": ("が", "ガ"), "gi": ("ぎ", "ギ"), "gu": ("ぐ", "グ"), "ge": ("げ", "ゲ"), "go": ("ご", "ゴ"), "za": ("ざ", "ザ"), "ji": ("じ", "ジ"), "zu": ("ず", "ズ"), "ze": ("ぜ", "ゼ"), "zo": ("ぞ", "ゾ"), "da": ("だ", "ダ"), "di": ("ぢ", "ヂ"), "du": ("づ", "ヅ"), "de": ("で", "デ"), "do": ("ど", "ド"), "ba": ("ば", "バ"), "bi": ("び", "ビ"), "bu": ("ぶ", "ブ"), "be": ("べ", "ベ"), "bo": ("ぼ", "ボ"), "pa": ("ぱ", "パ"), "pi": ("ぴ", "ピ"), "pu": ("ぷ", "プ"), "pe": ("ぺ", "ペ"), "po": ("ぽ", "ポ"), "kya": ("きゃ", "キャ"), "kyu": ("きゅ", "キュ"), "kyo": ("きょ", "キョ"), "gya": ("ぎゃ", "ギャ"), "gyu": ("ぎゅ", "ギュ"), "gyo": ("ぎょ", "ギョ"), "sha": ("しゃ", "シャ"), "shu": ("しゅ", "シュ"), "sho": ("しょ", "ショ"), "ja": ("じゃ", "ジャ"), "ju": ("じゅ", "ジュ"), "jo": ("じょ", "ジョ"), "cha": ("ちゃ", "チャ"), "chu": ("ちゅ", "チュ"), "cho": ("ちょ", "チョ"), "dya": ("ぢゃ", "ヂャ"), "dyu": ("ぢゅ", "ヂュ"), "dyo": ("ぢょ", "ヂョ"), "nya": ("にゃ", "ニャ"), "nyu": ("にゅ", "ニュ"), "nyo": ("にょ", "ニョ"), "hya": ("ひゃ", "ヒャ"), "hyu": ("ひゅ", "ヒュ"), "hyo": ("ひょ", "ヒョ"), "bya": ("びゃ", "ビャ"), "byu": ("びゅ", "ビュ"), "byo": ("びょ", "ビョ"), "pya": ("ぴゃ", "ピャ"), "pyu": ("ぴゅ", "ピュ"), "pyo": ("ぴょ", "ピョ"), "mya": ("みゃ", "ミャ"), "myu": ("みゅ", "ミュ"), "myo": ("みょ", "ミョ"), "rya": ("りゃ", "リャ"), "ryu": ("りゅ", "リュ"), "ryo": ("りょ", "リョ"), } # ========== 按行分组 ========== # 行名与对应的罗马音列表(可根据需要添加更多行) rows = { "a": ["a", "i", "u", "e", "o"], "ka": ["ka", "ki", "ku", "ke", "ko"], "sa": ["sa", "shi", "su", "se", "so"], "ta": ["ta", "chi", "tsu", "te", "to"], "na": ["na", "ni", "nu", "ne", "no"], "ha": ["ha", "hi", "fu", "he", "ho"], "ma": ["ma", "mi", "mu", "me", "mo"], "ya": ["ya", "yu", "yo"], "ra": ["ra", "ri", "ru", "re", "ro"], "wa": ["wa", "wo"], "n": ["n"], "ga": ["ga", "gi", "gu", "ge", "go"], "za": ["za", "ji", "zu", "ze", "zo"], "da": ["da", "di", "du", "de", "do"], "ba": ["ba", "bi", "bu", "be", "bo"], "pa": ["pa", "pi", "pu", "pe", "po"], "kya": ["kya", "kyu", "kyo"], "gya": ["gya", "gyu", "gyo"], "sha": ["sha", "shu", "sho"], "ja": ["ja", "ju", "jo"], "cha": ["cha", "chu", "cho"], "dya": ["dya", "dyu", "dyo"], "nya": ["nya", "nyu", "nyo"], "hya": ["hya", "hyu", "hyo"], "bya": ["bya", "byu", "byo"], "pya": ["pya", "pyu", "pyo"], "mya": ["mya", "myu", "myo"], "rya": ["rya", "ryu", "ryo"], } # 反向映射(假名 -> 罗马音) hira_to_romaji = {v[0]: k for k, v in kana_dict.items()} kata_to_romaji = {v[1]: k for k, v in kana_dict.items()} # 所有罗马音列表(用于默认全范围) all_romaji = list(kana_dict.keys()) # ========== 错题本 ========== # 每个条目:{'mode': 模式编号, 'question': 题目内容, 'correct': 正确答案(字符串或元组), 'count': 错误次数} mistakes = [] starred_romaji = [] # 存储用户星标的罗马音 # ========== 错题本辅助函数 ========== def _add_mistake(mode, question, correct): """将错题添加到全局错题本,如果已存在则增加次数,否则新增""" global mistakes for item in mistakes: if item['mode'] == mode and item['question'] == question: item['count'] += 1 return mistakes.append({ 'mode': mode, 'question': question, 'correct': correct, 'count': 1 }) mode_names = { 1: "罗马音→假名", 2: "平假名→片假名+罗马音", 3: "片假名→平假名+罗马音", 4: "任意假名→罗马音+另一假名", } # ========== 通用重测函数 ========== def retry_mistakes(mode, current_mistakes, ask_func): """ 通用重测函数 :param mode: 模式编号 (1-4),仅用于显示或备用,实际未使用 :param current_mistakes: 待重测的核心词列表 :param ask_func: 接受一个核心词,执行出题交互,返回用户是否答对 (True/False),内部处理错题记录 """ if not current_mistakes: return print(f"\n本次练习中你答错了 {len(current_mistakes)} 个词。") retry = input("是否重测这些错题?(y/n): ").strip().lower() if retry != 'y': return while current_mistakes: item = random.choice(current_mistakes) if ask_func(item): current_mistakes.remove(item) print("很好!已从重测列表中移除。") else: # ask_func 内部已处理错题记录 print("已更新错题本。") cont = input("\n输入 0 返回主页,按回车继续重测:").strip() if cont == '0': break print("重测结束。") # ========== 范围选择函数 ========== def select_range(): """让用户选择要练习的行,返回该范围内的罗马音列表""" print("\n--- 选择练习范围 ---") print("可用的行标识(可输入多个,用空格分隔):") # 列出所有行名 row_names = list(rows.keys()) # 每行显示几个,便于阅读 for i in range(0, len(row_names), 6): print(" " + " ".join(row_names[i:i+6])) print("例如:输入 'a ka' 表示あ行和か行,直接回车表示所有行") inp = input("请输入行标识:").strip().lower() if inp == "": print("已选择全部行") return all_romaji.copy() # 返回所有罗马音的副本 # 解析输入,可能包含多个行名 selected_rows = inp.split() selected_romaji = set() for row in selected_rows: if row in rows: selected_romaji.update(rows[row]) else: print(f"警告:未知的行标识 '{row}',已忽略") if not selected_romaji: print("未选择任何有效行,将使用全部行") return all_romaji.copy() # 转换为列表并返回 result = list(selected_romaji) print(f"已选择 {len(result)} 个罗马音:{', '.join(sorted(result))}") return result # ========== 主页菜单 ========== def main_menu(): print("\n========== 日语五十音练习 ==========") print("1. 给出罗马音自查假名") print("2. 给出平假名自查片假名并输入罗马音") print("3. 给出片假名自查平假名并输入罗马音") print("4. 给出任意假名输入罗马音和另一假名") print("5. 查看错题本") print("6. 错题本练习") print("7. 考试模式") print("8. 星标管理") print("0. 退出程序") choice = input("请输入数字选择功能:").strip() return choice # ========== 功能1:罗马音→假名(带重测错题) ========== def romaji_to_kana(): print("\n--- 罗马音 → 假名练习 ---") roma_list = select_range() if not roma_list: print("无有效罗马音,返回主页") return current_mistakes = [] # 本次练习中答错的罗马音(唯一) while True: roma = random.choice(roma_list) print(f"\n罗马音:{roma}") print("请在纸上写出对应的平假名和片假名。") input("写完后按回车键查看正确答案...") correct_ping, correct_pian = kana_dict[roma] print(f"正确答案:平假名 {correct_ping},片假名 {correct_pian}") while True: feedback = input("你写对了吗?(y/n): ").strip().lower() if feedback in ('y', 'n'): break print("请输入 y 或 n") if feedback == 'n': # 记录错题(统一使用辅助函数) _add_mistake(1, roma, (correct_ping, correct_pian)) if roma not in current_mistakes: current_mistakes.append(roma) print("已记录到错题本。") else: print("很好!") cont = input("\n输入 0 返回主页,按回车继续练习:").strip() if cont == '0': break # 重测本次错题 if current_mistakes: def ask_retry(roma): print(f"\n【重测】罗马音:{roma}") print("请在纸上写出对应的平假名和片假名。") input("写完后按回车键查看正确答案...") correct_ping, correct_pian = kana_dict[roma] print(f"正确答案:平假名 {correct_ping},片假名 {correct_pian}") while True: feedback = input("你写对了吗?(y/n): ").strip().lower() if feedback in ('y', 'n'): break print("请输入 y 或 n") if feedback == 'n': _add_mistake(1, roma, (correct_ping, correct_pian)) return False return True retry_mistakes(1, current_mistakes, ask_retry) # ========== 功能2:平假名→片假名+罗马音 ========== def hiragana_to_katakana_and_romaji(): print("\n--- 平假名 → 片假名 + 罗马音 练习 ---") roma_list = select_range() if not roma_list: return # 根据选中的罗马音生成对应的平假名列表 hira_list = [kana_dict[r][0] for r in roma_list] current_mistakes = [] # 存储本次答错的平假名 while True: hira = random.choice(hira_list) roma = hira_to_romaji[hira] correct_pian = kana_dict[roma][1] print(f"\n平假名:{hira}") print("请在纸上写出对应的片假名,并输入其罗马音。") input("写完后按回车键继续...") user_roma = input("请输入该假名的罗马音:").strip().lower() print(f"正确答案:片假名 {correct_pian},罗马音 {roma}") while True: feedback = input("你写对了吗(片假名和罗马音都正确)?(y/n): ").strip().lower() if feedback in ('y', 'n'): break print("请输入 y 或 n") if feedback == 'n': _add_mistake(2, hira, (correct_pian, roma)) if hira not in current_mistakes: current_mistakes.append(hira) print("已记录到错题本。") else: print("很好!") cont = input("\n输入 0 返回主页,按回车继续练习:").strip() if cont == '0': break # 重测本次错题 if current_mistakes: def ask_retry(hira): roma = hira_to_romaji[hira] correct_pian = kana_dict[roma][1] print(f"\n【重测】平假名:{hira}") print("请在纸上写出对应的片假名,并输入其罗马音。") input("写完后按回车键继续...") user_roma = input("请输入该假名的罗马音:").strip().lower() print(f"正确答案:片假名 {correct_pian},罗马音 {roma}") while True: feedback = input("你写对了吗(片假名和罗马音都正确)?(y/n): ").strip().lower() if feedback in ('y', 'n'): break print("请输入 y 或 n") if feedback == 'n': _add_mistake(2, hira, (correct_pian, roma)) return False return True retry_mistakes(2, current_mistakes, ask_retry) # ========== 功能3:片假名→平假名+罗马音 ========== def katakana_to_hiragana_and_romaji(): print("\n--- 片假名 → 平假名 + 罗马音 练习 ---") roma_list = select_range() if not roma_list: return kata_list = [kana_dict[r][1] for r in roma_list] current_mistakes = [] # 存储本次答错的片假名 while True: kata = random.choice(kata_list) roma = kata_to_romaji[kata] correct_hira = kana_dict[roma][0] print(f"\n片假名:{kata}") print("请在纸上写出对应的平假名,并输入其罗马音。") input("写完后按回车键继续...") user_roma = input("请输入该假名的罗马音:").strip().lower() print(f"正确答案:平假名 {correct_hira},罗马音 {roma}") while True: feedback = input("你写对了吗(平假名和罗马音都正确)?(y/n): ").strip().lower() if feedback in ('y', 'n'): break print("请输入 y 或 n") if feedback == 'n': _add_mistake(3, kata, (correct_hira, roma)) if kata not in current_mistakes: current_mistakes.append(kata) print("已记录到错题本。") else: print("很好!") cont = input("\n输入 0 返回主页,按回车继续练习:").strip() if cont == '0': break # 重测本次错题 if current_mistakes: def ask_retry(kata): roma = kata_to_romaji[kata] correct_hira = kana_dict[roma][0] print(f"\n【重测】片假名:{kata}") print("请在纸上写出对应的平假名,并输入其罗马音。") input("写完后按回车键继续...") user_roma = input("请输入该假名的罗马音:").strip().lower() print(f"正确答案:平假名 {correct_hira},罗马音 {roma}") while True: feedback = input("你写对了吗(平假名和罗马音都正确)?(y/n): ").strip().lower() if feedback in ('y', 'n'): break print("请输入 y 或 n") if feedback == 'n': _add_mistake(3, kata, (correct_hira, roma)) return False return True retry_mistakes(3, current_mistakes, ask_retry) # ========== 功能4:任意假名→罗马音+另一假名 ========== def random_kana_to_romaji_and_other(): print("\n--- 任意假名 → 罗马音 + 另一假名 练习 ---") roma_list = select_range() if not roma_list: return # 构建该范围内所有可能出现的假名(平假名和片假名) possible_hira = [kana_dict[r][0] for r in roma_list] possible_kata = [kana_dict[r][1] for r in roma_list] current_mistakes = [] # 存储本次答错的假名 while True: # 随机选择展示平假名或片假名 if random.choice([True, False]): question = random.choice(possible_hira) roma = hira_to_romaji[question] correct_other = kana_dict[roma][1] other_type = "片假名" else: question = random.choice(possible_kata) roma = kata_to_romaji[question] correct_other = kana_dict[roma][0] other_type = "平假名" print(f"\n假名:{question}") print("请在纸上写出对应的罗马音和另一种假名。") input("写完后按回车键继续...") user_roma = input("请输入罗马音:").strip().lower() user_other = input(f"请输入{other_type}:").strip() print(f"正确答案:罗马音 {roma},{other_type} {correct_other}") while True: feedback = input("你写对了吗?(y/n): ").strip().lower() if feedback in ('y', 'n'): break print("请输入 y 或 n") if feedback == 'n': _add_mistake(4, question, (roma, correct_other)) if question not in current_mistakes: current_mistakes.append(question) print("已记录到错题本。") else: print("很好!") cont = input("\n输入 0 返回主页,按回车继续练习:").strip() if cont == '0': break # 重测本次错题 if current_mistakes: def ask_retry(question): if question in hira_to_romaji: roma = hira_to_romaji[question] correct_other = kana_dict[roma][1] other_type = "片假名" else: roma = kata_to_romaji[question] correct_other = kana_dict[roma][0] other_type = "平假名" print(f"\n【重测】假名:{question}") print("请在纸上写出对应的罗马音和另一种假名。") input("写完后按回车键继续...") user_roma = input("请输入罗马音:").strip().lower() user_other = input(f"请输入{other_type}:").strip() print(f"正确答案:罗马音 {roma},{other_type} {correct_other}") while True: feedback = input("你写对了吗?(y/n): ").strip().lower() if feedback in ('y', 'n'): break print("请输入 y 或 n") if feedback == 'n': _add_mistake(4, question, (roma, correct_other)) return False return True retry_mistakes(4, current_mistakes, ask_retry) # ========== 功能5:查看错题本 ========== def show_mistakes(): print("\n========== 错题本 ==========") if not mistakes: print("暂无错题,继续加油!") input("按回车键返回主页...") return for mode in range(1, 5): mode_items = [item for item in mistakes if item['mode'] == mode] if mode_items: print(f"\n【{mode_names[mode]}】") for item in mode_items: if mode == 1: correct = item['correct'] print(f" 罗马音 {item['question']} → 平假名 {correct[0]}, 片假名 {correct[1]} (错误次数: {item['count']})") elif mode == 2: correct = item['correct'] print(f" 平假名 {item['question']} → 片假名 {correct[0]}, 罗马音 {correct[1]} (错误次数: {item['count']})") elif mode == 3: correct = item['correct'] print(f" 片假名 {item['question']} → 平假名 {correct[0]}, 罗马音 {correct[1]} (错误次数: {item['count']})") elif mode == 4: correct = item['correct'] print(f" 假名 {item['question']} → 罗马音 {correct[0]}, 另一假名 {correct[1]} (错误次数: {item['count']})") input("\n按回车键返回主页...") def mistake_practice(): global mistakes # 确保可以修改全局变量 print("\n--- 错题本练习 ---") if not mistakes: print("错题本为空,无法练习。") input("按回车键返回主页...") return # 显示当前错题统计 print("当前错题统计:") for mode in range(1, 5): mode_count = sum(1 for item in mistakes if item['mode'] == mode) if mode_count > 0: print(f" {mode_names[mode]}: {mode_count} 条") # 选择练习模式 print("\n请选择要练习的模式:") print("1. 罗马音→假名") print("2. 平假名→片假名+罗马音") print("3. 片假名→平假名+罗马音") print("4. 任意假名→罗马音+另一假名") print("5. 全部模式") mode_choice = input("请输入数字:").strip() if mode_choice not in ['1','2','3','4','5']: print("无效选择,返回主页。") return if mode_choice == '5': selected_items = mistakes.copy() else: selected_mode = int(mode_choice) selected_items = [item for item in mistakes if item['mode'] == selected_mode] if not selected_items: print("所选模式下无错题,返回主页。") return # 为每个条目添加临时连续正确计数 practice_items = [] for item in selected_items: new_item = item.copy() new_item['consecutive'] = 0 practice_items.append(new_item) print(f"\n开始练习,共 {len(practice_items)} 个错题。连续答对两次将从错题本移除。") while practice_items: item = random.choice(practice_items) mode = item['mode'] question = item['question'] correct = item['correct'] consecutive = item['consecutive'] print(f"\n【当前错误次数:{item['count']},已连续答对:{consecutive}次】") # 根据模式生成题目 if mode == 1: roma = question print(f"罗马音:{roma}") print("请在纸上写出对应的平假名和片假名。") input("写完后按回车键查看正确答案...") print(f"正确答案:平假名 {correct[0]},片假名 {correct[1]}") elif mode == 2: hira = question roma = hira_to_romaji[hira] correct_pian = correct[0] print(f"平假名:{hira}") print("请在纸上写出对应的片假名,并输入其罗马音。") input("写完后按回车键继续...") user_roma = input("请输入该假名的罗马音:").strip().lower() print(f"正确答案:片假名 {correct_pian},罗马音 {roma}") elif mode == 3: kata = question roma = kata_to_romaji[kata] correct_hira = correct[0] print(f"片假名:{kata}") print("请在纸上写出对应的平假名,并输入其罗马音。") input("写完后按回车键继续...") user_roma = input("请输入该假名的罗马音:").strip().lower() print(f"正确答案:平假名 {correct_hira},罗马音 {roma}") elif mode == 4: kana = question if kana in hira_to_romaji: roma = hira_to_romaji[kana] other_type = "片假名" correct_other = correct[1] else: roma = kata_to_romaji[kana] other_type = "平假名" correct_other = correct[1] print(f"假名:{kana}") print("请在纸上写出对应的罗马音和另一种假名。") input("写完后按回车键继续...") user_roma = input("请输入罗马音:").strip().lower() user_other = input(f"请输入{other_type}:").strip() print(f"正确答案:罗马音 {roma},{other_type} {correct_other}") while True: feedback = input("你写对了吗?(y/n): ").strip().lower() if feedback in ('y', 'n'): break print("请输入 y 或 n") if feedback == 'y': item['consecutive'] += 1 if item['consecutive'] >= 2: for i, mitem in enumerate(mistakes): if mitem['mode'] == item['mode'] and mitem['question'] == item['question']: del mistakes[i] break practice_items.remove(item) print("连续答对两次!已从错题本中移除。") else: print(f"答对一次,再答对一次即可移除。") else: item['consecutive'] = 0 for mitem in mistakes: if mitem['mode'] == item['mode'] and mitem['question'] == item['question']: mitem['count'] += 1 break print("已记录错误,继续加油。") cont = input("\n输入 0 返回主页,按回车继续练习:").strip() if cont == '0': break print("错题本练习结束。") def exam_mode(): print("\n========== 考试模式 ==========") # 范围选择 print("请选择考试范围:") print("1. 按行选择") print("2. 使用星标词") range_choice = input("请输入数字:").strip() if range_choice == '1': roma_list = select_range() elif range_choice == '2': if not starred_romaji: print("星标列表为空,无法使用星标范围。") return roma_list = starred_romaji.copy() print(f"已选择星标词,共 {len(roma_list)} 个罗马音。") else: print("无效选择,返回主页。") return if not roma_list: return # 题目总数设定 max_questions = len(roma_list) * 2 print(f"\n范围内罗马音数量:{len(roma_list)},最大题目数(每个最多2次):{max_questions}") while True: try: total = int(input("请输入题目总数:").strip()) if total <= 0: print("题目数必须大于0。") continue if total > max_questions: print(f"题目数不能超过最大题目数 {max_questions},请重新输入。") continue break except ValueError: print("请输入有效的数字。") # 生成考试题目列表 used_count = {roma: 0 for roma in roma_list} exam_questions = [] while len(exam_questions) < total: available = [r for r in roma_list if used_count[r] < 2] if not available: break roma = random.choice(available) mode = random.randint(1, 4) exam_questions.append((roma, mode)) used_count[roma] += 1 random.shuffle(exam_questions) print(f"\n考试开始,共 {len(exam_questions)} 题。") correct_count = 0 total_questions = len(exam_questions) for idx, (roma, mode) in enumerate(exam_questions, 1): print(f"\n--- 第 {idx} 题 ---") hira, kata = kana_dict[roma] if mode == 1: print(f"罗马音:{roma}") print("请在纸上写出对应的平假名和片假名。") input("写完后按回车键查看正确答案...") print(f"正确答案:平假名 {hira},片假名 {kata}") while True: feedback = input("你写对了吗?(y/n): ").strip().lower() if feedback in ('y', 'n'): break print("请输入 y 或 n") if feedback == 'y': correct_count += 1 print("✓ 正确") else: print("✗ 错误") _add_mistake(1, roma, (hira, kata)) elif mode == 2: print(f"平假名:{hira}") print("请在纸上写出对应的片假名,并输入其罗马音。") user_roma = input("请输入罗马音:").strip().lower() print(f"正确答案:片假名 {kata},罗马音 {roma}") while True: feedback = input("你写的片假名正确吗?(y/n): ").strip().lower() if feedback in ('y', 'n'): break print("请输入 y 或 n") roma_correct = (user_roma == roma) kana_correct = (feedback == 'y') if roma_correct and kana_correct: correct_count += 1 print("✓ 正确") else: print("✗ 错误") _add_mistake(2, hira, (kata, roma)) elif mode == 3: print(f"片假名:{kata}") print("请在纸上写出对应的平假名,并输入其罗马音。") user_roma = input("请输入罗马音:").strip().lower() print(f"正确答案:平假名 {hira},罗马音 {roma}") while True: feedback = input("你写的平假名正确吗?(y/n): ").strip().lower() if feedback in ('y', 'n'): break print("请输入 y 或 n") roma_correct = (user_roma == roma) kana_correct = (feedback == 'y') if roma_correct and kana_correct: correct_count += 1 print("✓ 正确") else: print("✗ 错误") _add_mistake(3, kata, (hira, roma)) elif mode == 4: if random.choice([True, False]): show_kana = hira other_type = "片假名" correct_other = kata else: show_kana = kata other_type = "平假名" correct_other = hira print(f"假名:{show_kana}") print("请在纸上写出对应的罗马音和另一种假名。") user_roma = input("请输入罗马音:").strip().lower() user_other = input(f"请输入{other_type}:").strip() print(f"正确答案:罗马音 {roma},{other_type} {correct_other}") while True: feedback = input("你写对了吗?(y/n): ").strip().lower() if feedback in ('y', 'n'): break print("请输入 y 或 n") roma_correct = (user_roma == roma) other_correct = (user_other == correct_other) if roma_correct and other_correct and feedback == 'y': correct_count += 1 print("✓ 正确") else: print("✗ 错误") _add_mistake(4, show_kana, (roma, correct_other)) print("\n========== 考试结束 ==========") print(f"总分:{correct_count}/{total_questions}") input("按回车键返回主页...") def star_management(): print("\n========== 星标管理 ==========") while True: print("\n请选择操作:") print("1. 查看星标词") print("2. 添加星标词") print("3. 移除星标词") print("0. 返回主页") choice = input("请输入数字:").strip() if choice == '1': if not starred_romaji: print("星标列表为空。") else: print("\n当前星标词(罗马音 -> 平假名, 片假名):") for roma in sorted(starred_romaji): hira, kata = kana_dict[roma] print(f" {roma} -> {hira}, {kata}") elif choice == '2': roma = input("请输入要添加的罗马音:").strip().lower() if roma not in kana_dict: print("无效的罗马音,请检查。") elif roma in starred_romaji: print("该词已在星标列表中。") else: starred_romaji.append(roma) print(f"已添加 {roma} 到星标列表。") elif choice == '3': roma = input("请输入要移除的罗马音:").strip().lower() if roma in starred_romaji: starred_romaji.remove(roma) print(f"已移除 {roma}。") else: print("该词不在星标列表中。") elif choice == '0': break else: print("无效选择,请重新输入。") # ========== 主程序 ========== def main(): while True: choice = main_menu() if choice == '1': romaji_to_kana() elif choice == '2': hiragana_to_katakana_and_romaji() elif choice == '3': katakana_to_hiragana_and_romaji() elif choice == '4': random_kana_to_romaji_and_other() elif choice == '5': show_mistakes() elif choice == '6': mistake_practice() elif choice == '7': exam_mode() elif choice == '8': star_management() elif choice == '0': print("感谢使用,再见!") break else: print("无效输入,请重新选择。") if __name__ == "__main__": main()