用python编写一个初中信息科技选择题练习系统
软件说明:选择题练习系统
1. 软件简介
选择题练习系统是一款基于 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 tk
from tkinter import ttk, messagebox
import pandas as pd
import random
import sys
import os
def 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()
运行界面如图: