选择题练习系统是一款基于 Python 开发的图形化应用程序,旨在帮助用户通过随机抽取题目进行练习,并实时查看答题结果和错题分析。系统支持从 CSV 文件中读取题目,并提供了友好的用户界面,方便用户进行答题和查看错题。
2. 主要功能随机抽题:系统从题库中随机抽取 10 道题目,用户逐题作答。答题界面:每道题目显示题目内容和四个选项,用户点击选项即可选择答案。题目前显示当前第几题(如“第 1 题”)。得分统计:每答对一题得 10 分,总分满分为 100 分。答题结束后,系统会显示用户的总分。错题分析:答题结束后,用户可以查看错题。错题界面显示题目、选项内容、用户答案和正确答案。错题内容支持滚动查看,适合错题较多的情况。题库支持:系统从 questions.csv 文件中读取题目,支持自定义题库。题库文件格式为 CSV,包含以下字段:question:题目内容。optionA、optionB、optionC、optionD:四个选项。correctAnswer:正确答案(如 A、B、C、D)。3. 使用说明3.1 运行环境操作系统:Windows、macOS、Linux。Python 版本:Python 3.6 及以上。依赖库:tkinter、pandas。3.2 运行方式直接运行 Python 脚本:确保已安装 Python 和依赖库。将 选择题练习.py 和 questions.csv 放在同一目录下。运行以下命令启动程序:python 选择题练习.py运行可执行文件:使用 PyInstaller 将脚本打包为可执行文件(如 选择题练习.exe)。双击 选择题练习.exe 即可运行程序。3.3 操作步骤启动程序:运行程序后,主界面会显示第一道题目和四个选项。答题:点击选项按钮选择答案。点击“下一题”按钮继续答题。查看总分:答完 10 题后,系统会显示总分。查看错题:点击“查看错题”按钮,弹出一个新窗口显示所有错题及其详细信息。4. 题库文件格式题库文件 questions.csv 的格式如下:
question
optionA
optionB
optionC
optionD
correctAnswer
Python是一种什么类型的语言?
编译型
解释型
汇编型
机器语言
B
以下哪个是Python的关键字?
class
function
method
loop
A
Python中用于定义函数的关键字是?
def
function
define
func
A
5. 注意事项题库文件编码:确保 questions.csv 文件的编码为 gbk 或 utf-8,否则可能导致程序无法正确读取题目。文件路径:如果直接运行 Python 脚本,确保 questions.csv 文件与脚本在同一目录下。如果运行可执行文件,questions.csv 文件会被打包到可执行文件中,无需额外放置。错题显示:如果错题较多,错题界面支持滚动查看,确保所有错题都能显示。6. 扩展功能增加题目数量:允许用户选择抽取的题目数量。支持多种题型:如多选题、填空题等。保存答题记录:将用户的答题记录保存到文件中,方便后续分析。import tkinter as tkfrom tkinter import ttk, messageboximport pandas as pdimport randomimport sysimport osdef get_resource_path(relative_path): """获取资源的绝对路径""" if hasattr(sys, '_MEIPASS'): # 打包后的路径 return os.path.join(sys._MEIPASS, relative_path) # 开发环境中的路径 return os.path.join(os.path.abspath("."), relative_path)class QuizApp: def __init__(self, root): self.root = root self.root.title("初中信息科技练习系统V1.0") # 设置窗口大小 self.root.geometry("600x400") # 读取 CSV 文件,指定编码为 gbk self.questions_df = pd.read_csv(get_resource_path("questions.csv"), encoding='gbk') # 随机抽取 10 题 self.selected_questions = self.questions_df.sample(n=10).reset_index(drop=True) self.current_question_index = 0 self.score = 0 # 创建界面元素 self.question_label = tk.Label(root, text="", font=("Arial", 14), wraplength=500) self.question_label.pack(pady=20) self.option_buttons = [] for i in range(4): button = tk.Button(root, text="", font=("Arial", 12), width=20, command=lambda i=i: self.check_answer(i)) button.pack(pady=5) self.option_buttons.append(button) self.next_button = tk.Button(root, text="下一题", font=("Arial", 12), command=self.next_question) self.next_button.pack(pady=20) self.score_label = tk.Label(root, text="", font=("Arial", 14)) self.score_label.pack(pady=10) self.wrong_answers_button = tk.Button(root, text="查看错题", font=("Arial", 12), command=self.show_wrong_answers) self.wrong_answers_button.pack(pady=10) self.wrong_answers_button.config(state=tk.DISABLED) # 存储错题 self.wrong_answers = [] # 显示第一题 self.show_question() def show_question(self): """显示当前题目""" if self.current_question_index < len(self.selected_questions): question = self.selected_questions.iloc[self.current_question_index] # 显示当前第几题 self.question_label.config(text=f"第 {self.current_question_index + 1} 题:{question['question']}") options = [question['optionA'], question['optionB'], question['optionC'], question['optionD']] for i, button in enumerate(self.option_buttons): button.config(text=options[i]) else: self.show_score() def check_answer(self, selected_option): """检查答案是否正确""" question = self.selected_questions.iloc[self.current_question_index] correct_answer = question['correctAnswer'].strip().upper() # 去除空格并转换为大写 # 获取用户选择的选项 selected_answer = chr(ord('A') + selected_option) if selected_answer == correct_answer: self.score += 10 # 做对一题得 10 分 else: # 只有答错的题目才会被记录 self.wrong_answers.append({ 'question': question['question'], 'options': { 'A': question['optionA'], 'B': question['optionB'], 'C': question['optionC'], 'D': question['optionD'] }, 'correct_answer': correct_answer, 'user_answer': selected_answer }) # 显示下一题 self.next_question() def next_question(self): """显示下一题""" self.current_question_index += 1 if self.current_question_index < len(self.selected_questions): self.show_question() else: self.show_score() def show_score(self): """显示总分""" self.question_label.config(text="答题结束!") for button in self.option_buttons: button.config(state=tk.DISABLED) self.next_button.config(state=tk.DISABLED) self.score_label.config(text=f"你的总分是:{self.score}/100") self.wrong_answers_button.config(state=tk.NORMAL) def show_wrong_answers(self): """显示错题""" if not self.wrong_answers: messagebox.showinfo("错题", "没有错题!") return # 创建新窗口显示错题 wrong_answers_window = tk.Toplevel(self.root) wrong_answers_window.title("错题及正确答案") wrong_answers_window.geometry("600x400") # 创建滚动条 scrollbar = tk.Scrollbar(wrong_answers_window) scrollbar.pack(side=tk.RIGHT, fill=tk.Y) # 创建文本框 wrong_answers_text = tk.Text(wrong_answers_window, wrap=tk.WORD, yscrollcommand=scrollbar.set) wrong_answers_text.pack(fill=tk.BOTH, expand=True) # 添加错题内容 for i, wrong_answer in enumerate(self.wrong_answers): wrong_answers_text.insert(tk.END, f"{i+1}. 题目:{wrong_answer['question']}\n") wrong_answers_text.insert(tk.END, f" 选项:\n") wrong_answers_text.insert(tk.END, f" A: {wrong_answer['options']['A']}\n") wrong_answers_text.insert(tk.END, f" B: {wrong_answer['options']['B']}\n") wrong_answers_text.insert(tk.END, f" C: {wrong_answer['options']['C']}\n") wrong_answers_text.insert(tk.END, f" D: {wrong_answer['options']['D']}\n") wrong_answers_text.insert(tk.END, f" 你的答案:{wrong_answer['user_answer']}\n") wrong_answers_text.insert(tk.END, f" 正确答案:{wrong_answer['correct_answer']}\n\n") # 配置滚动条 scrollbar.config(command=wrong_answers_text.yview) # 禁用文本框编辑 wrong_answers_text.config(state=tk.DISABLED)# 创建主窗口root = tk.Tk()# 创建抽题应用app = QuizApp(root)# 运行主循环root.mainloop()运行界面如图:

运行界面如图所示