自定义刷题工具-python实现

背景:

最近想要刷题,虽然目前有很多成熟的软件,网站。但是能够支持自定义的导入题库的非常少,或者是要么让你开会员,而直接百度题库的话,正确答案就摆在你一眼能看见的地方,看的时候总觉得自己也会,然后考的时候又啥都不记得了,然后最重要的一点是自定义导入,否则现如今成熟的牛客力扣啥才是最优的选择

自定义题库要素A

这个是百度的时候发现的
1 题号
2 问题题干
3 类型(单选,多选,文本)
4 选项(单选多选的选项,实际上判断题也可以归为2个选项的单选题)

5 参考答案

6 答案详解,开发完成后加入的,感觉光是答案不太好

7 上次答案记录。后续加入的,你连上次做的对的错的都不知道的话,刷题的意义性何在?

8 标签:也是后续加上的,本来是打算数据多了做一个条件查询的,但是发现python的查询太丑了,可能是我打开方式不对,因此我想了一个办法就是把问题标签化,你可以通过标签来做筛选,因此你可以只看某部分标签内的题

代码:

代码结构如下:注意python的名称好像不太重要可以随意改
 

ExerciseDemo1.py
questions.json
QuestionsJsonGenerator.py
题库文件夹 里面可以放你自己的各种文档,当然你可以放在一个xlsx文件里面也行,但是数据多了好不好用我就不负责了

ExerciseDemo1.py
 

import json
import tkinter as tk
from tkinter import ttk# 从JSON文件中加载题目
with open('questions.json', 'r', encoding='utf-8') as file:data = json.load(file)questions = data['questions']# 获取所有标签并生成唯一标签列表
tags_set = set()
for question in questions:tags_set.update(question['tags'])
tags_list = list(tags_set)# 创建主窗口
root = tk.Tk()
root.title("刷题软件")
root.geometry('1200x800')current_question_index = 0# 切换题目
def load_question(index):global current_question_indexcurrent_question_index = indexquestion_data = questions[current_question_index]question_label.config(text=f"{question_data['id']}. {question_data['question']}")# 清空当前答案框架for widget in answer_frame.winfo_children():widget.destroy()global answer_varanswer_var = Noneif question_data["type"] == "single":answer_var = tk.StringVar()for key, value in question_data["options"].items():rb = tk.Radiobutton(answer_frame, text=value, variable=answer_var, value=key)rb.pack(anchor='w')elif question_data["type"] == "multiple":answer_var = {}for key, value in question_data["options"].items():var = tk.BooleanVar()answer_var[key] = varcb = tk.Checkbutton(answer_frame, text=value, variable=var)cb.pack(anchor='w')elif question_data["type"] == "text":answer_var = tk.Text(answer_frame, height=5, wrap="word")answer_var.pack(fill='both', expand=True)# 清空答案显示区域并滚动至顶部answer_display.delete("1.0", tk.END)answer_display.yview_moveto(0)# 显示答案
def show_answer():question = questions[current_question_index]answer = question['answer']explanation = question['explanation']last_answer = question.get('lastAnswer', None)answer_display.delete('1.0', tk.END)if last_answer:answer_display.insert(tk.END, f"答案:\n{answer}\n\n你的上次答案:\n{last_answer}\n\n解释:\n{explanation}")else:answer_display.insert(tk.END, f"答案:\n{answer}\n\n解释:\n{explanation}")answer_display.yview_moveto(0)# 隐藏答案
def hide_answer():answer_display.delete('1.0', tk.END)# 保存答案
def save_answer():question = questions[current_question_index]if question["type"] == "single":question['lastAnswer'] = answer_var.get()elif question["type"] == "multiple":question['lastAnswer'] = [key for key, var in answer_var.items() if var.get()]elif question["type"] == "text":question['lastAnswer'] = answer_var.get("1.0", tk.END).strip()with open('questions.json', 'w', encoding='utf-8') as file:json.dump({'questions': questions}, file, indent=2, ensure_ascii=False)# 更新标题下拉列表
def update_question_selector(tag=None):if tag:filtered_titles = [f"{q['id']}. {q['question']}" for q in questions if tag in q['tags']]else:filtered_titles = [f"{q['id']}. {q['question']}" for q in questions]question_selector['values'] = filtered_titlesif filtered_titles:question_selector.current(0)load_question(0)# 清除标签选择
def clear_tag_selection():tag_selector.set('')update_question_selector()# 标签下拉列表选项
tag_frame = tk.Frame(root)
tag_frame.pack(pady=10, anchor='w')tag_selector = ttk.Combobox(tag_frame, values=tags_list, width=50, state='readonly')
tag_selector.grid(row=0, column=0, padx=5)
tag_selector.bind("<<ComboboxSelected>>", lambda event: update_question_selector(tag_selector.get()))clear_tag_button = tk.Button(tag_frame, text="清除标签选择", command=clear_tag_selection)
clear_tag_button.grid(row=0, column=1, padx=5)# 标题下拉列表选项
question_titles = [f"{q['id']}. {q['question']}" for q in questions]
question_selector = ttk.Combobox(root, values=question_titles, width=100, state='readonly')
question_selector.current(0)
question_selector.pack(pady=10, anchor='w', fill=tk.X)
question_selector.bind("<<ComboboxSelected>>", lambda event: load_question(question_selector.current()))# 功能按钮
button_frame = tk.Frame(root)
button_frame.pack(pady=10, anchor='w')previous_button = tk.Button(button_frame, text="上一题", command=lambda: load_question((current_question_index - 1) % len(questions)))
previous_button.grid(row=0, column=0, padx=5)next_button = tk.Button(button_frame, text="下一题", command=lambda: load_question((current_question_index + 1) % len(questions)))
next_button.grid(row=0, column=1, padx=5)# 题干
question_label = tk.Label(root, text="", wraplength=600, justify="left")
question_label.pack(pady=10, anchor='w')# 答案框架
answer_frame = tk.Frame(root)
answer_frame.pack(pady=10, fill='both', expand=True, anchor='w')# 显示答案和隐藏答案按钮框架
show_hide_button_frame = tk.Frame(root)
show_hide_button_frame.pack(pady=5, anchor='w')save_answer_button = tk.Button(show_hide_button_frame, text="保存答案", command=save_answer)
save_answer_button.grid(row=0, column=0, padx=5)show_answer_button = tk.Button(show_hide_button_frame, text="显示答案", command=show_answer)
show_answer_button.grid(row=0, column=1, padx=5)hide_answer_button = tk.Button(show_hide_button_frame, text="隐藏答案", command=hide_answer)
hide_answer_button.grid(row=0, column=2, padx=5)# 显示答案区域框架
answer_display_frame = tk.Frame(root)
answer_display_frame.pack(pady=10, fill='both', expand=True)answer_display_scroll = tk.Scrollbar(answer_display_frame)
answer_display_scroll.pack(side=tk.RIGHT, fill=tk.Y)answer_display = tk.Text(answer_display_frame, height=4, yscrollcommand=answer_display_scroll.set)
answer_display.pack(fill='both', expand=True)answer_display_scroll.config(command=answer_display.yview)# 初始化加载第一题
load_question(0)# 运行主循环
root.mainloop()

questions.json

这个就不举例了,实际上是通过xlsx文件执行QuestionsJsonGenerator自动生成的。



QuestionsJsonGenerator.py
 

import json
import openpyxl
import os
import reclass QuestionsJsonGenerator:def __init__(self, excel_file, json_file):self.excel_file = excel_fileself.json_file = json_fileself.questions = []def read_excel(self):workbook = openpyxl.load_workbook(self.excel_file)sheet = workbook.activerows = list(sheet.iter_rows(values_only=True))headers = rows[0]for row in rows[1:]:question_data = {}for header, value in zip(headers, row):if header == "标签":question_data['tags'] = [tag for tag in re.split(r'[,,]', value) if tag.strip()]elif header == "类型":question_data['type'] = valueelif header == "问题":question_data['question'] = valueelif header == "答案":if question_data['type'] == "multiple":question_data['answer'] = re.split(r'[,,]', value)else:question_data['answer'] = valueelif header == "答案解释":question_data['explanation'] = value if value else ""elif header == "选项":# 使用不同的分隔符对选项进行分割raw_options = re.split(r'[;\n:;]+', value)# 去除空白项options = [opt.strip() for opt in raw_options if opt.strip()]question_data['options'] = {}for opt in options:# 允许使用 : 或 . 作为键值分隔符key_value = re.split(r'[:.]', opt)if len(key_value) == 2:key = key_value[0].strip()val = key_value[1].strip()question_data['options'][key] = val# 只有在处理完一行所有数据后才添加到 questions 列表中self.questions.append(question_data)# Add IDs to each questionfor i, question in enumerate(self.questions):question['id'] = i + 1def write_json(self):if os.path.exists(self.json_file):with open(self.json_file, 'r', encoding='utf-8') as file:data = json.load(file)else:data = {'questions': []}data['questions'] = self.questionswith open(self.json_file, 'w', encoding='utf-8') as file:json.dump(data, file, indent=2, ensure_ascii=False)def generate_json(self):self.read_excel()self.write_json()# 使用示例
excel_file = '题库/牛客-java.xlsx'  # 替换为你的Excel文件路径
json_file = 'questions.json'  # 替换为你的JSON文件路径generator = QuestionsJsonGenerator(excel_file, json_file)
generator.generate_json()
 

导入模板,数据准备演示

图例:

说明:

看图,自己最好设置一个模板,还有觉得我的这种切分不够你使用习惯的自己去改代码就行,下面说明在哪改吧

标签切分

if header == "标签":question_data['tags'] = [tag for tag in re.split(r'[,,]', value) if tag.strip()]

答案切分

elif header == "答案":if question_data['type'] == "multiple":question_data['answer'] = re.split(r'[,,]', value)else:question_data['answer'] = value

选项切分

elif header == "选项":# 使用不同的分隔符对选项进行分割raw_options = re.split(r'[;\n:;]+', value)# 去除空白项options = [opt.strip() for opt in raw_options if opt.strip()]question_data['options'] = {}for opt in options:# 允许使用 : 或 . 作为键值分隔符key_value = re.split(r'[:.]', opt)if len(key_value) == 2:key = key_value[0].strip()val = key_value[1].strip()question_data['options'][key] = val

执行QuestionsJsonGenerator.py

执行成功后检查一个json有没有问题,这里用我这里生成的截图做参考

主窗口程序演示

运行ExerciseDemo1.py

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/869374.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Gymnasium 借游戏来学习人工智能

既然有了免费的linux系统GPU&#xff0c;干脆演示一下使用drivecolab套件来训练模型。 !apt-get install -y build-essential swig !pip install box2d-py !pip install gymnasium[all] !pip install gymnasium[atari] gymnasium[accept-rom-license] !pip install stable_bas…

项目收获总结--Redis的知识收获

一、概述 最近几天公司项目开发上线完成&#xff0c;做个收获总结吧~ 今天记录Redis的收获和提升。 二、Redis异步队列 Redis做异步队列一般使用 list 结构作为队列&#xff0c;rpush 生产消息&#xff0c;lpop 消费消息。当 lpop 没有消息的时候&#xff0c;要适当sleep再…

深度学习pytorch多机多卡网络配置桥接方法

1 安装pdsh&#xff08;Parallel Distributed Shell&#xff09; sudo apt install pdsh sudo -s # 切换超级用户身份 …

MATLAB备赛资源库(1)建模指令

一、介绍 MATLAB&#xff08;Matrix Laboratory&#xff09;是一种强大的数值计算环境和编程语言&#xff0c;特别设计用于科学计算、数据分析和工程应用。 二、使用 数学建模使用MATLAB通常涉及以下几个方面&#xff1a; 1. **数据处理与预处理**&#xff1a; - 导入和处理…

Echarts实现github提交记录图

最近改个人博客&#xff0c;看了github的提交记录&#xff0c;是真觉得好看。可以移植到自己的博客上做文章统计 效果如下 代码如下 <!DOCTYPE html> <html lang"en" style"height: 100%"><head><meta charset"utf-8"> …

240709_昇思学习打卡-Day21-文本解码原理--以MindNLP为例

240709_昇思学习打卡-Day21-文本解码原理–以MindNLP为例 今天做根据前文预测下一个单词&#xff0c;仅作简单记录及注释。 一个文本序列的概率分布可以分解为每个词基于其上文的条件概率的乘积 &#x1d44a;_0:初始上下文单词序列&#x1d447;: 时间步当生成EOS标签时&a…

企业级网关设计

tips&#xff1a;本文完全来源于卢泽龙&#xff01;&#xff01;&#xff01; 一、Gateway概述 1.1设计目标 1.2gateway基本功能 中文文档参考&#xff1a;https://cloud.tencent.com/developer/article/1403887?from15425 三大核心&#xff1a; 二、引入依赖和yaml配置…

如何在 PostgreSQL 中确保数据的异地备份安全性?

文章目录 一、备份策略1. 全量备份与增量备份相结合2. 定义合理的备份周期3. 选择合适的备份时间 二、加密备份数据1. 使用 PostgreSQL 的内置加密功能2. 使用第三方加密工具 三、安全的传输方式1. SSH 隧道2. SFTP3. VPN 连接 四、异地存储的安全性1. 云存储服务2. 内部存储设…

人话学Python-基础篇-字符串

一&#xff1a;字符串的定义 在Python中使用引号来定义。不论是单引号还是双引号。 str1 Hello World str2 "Hello World" 二&#xff1a;字符串的访问 如果我们要取出字符串中单独的字符&#xff0c;需要使用方括号来表示取得的位置。如果要取出字符串的子串&…

原创作品—数据可视化大屏

设计数据可视化大屏时&#xff0c;用户体验方面需注重以下几点&#xff1a;首先&#xff0c;确保大屏信息层次分明&#xff0c;主要数据突出显示&#xff0c;次要信息适当弱化&#xff0c;帮助用户快速捕捉关键信息。其次&#xff0c;设计应直观易懂&#xff0c;避免复杂难懂的…

前端javascript中的排序算法之冒泡排序

冒泡排序&#xff08;Bubble Sort&#xff09;基本思想&#xff1a; 经过多次迭代&#xff0c;通过相邻元素之间的比较与交换&#xff0c;使值较小的元素逐步从后面移到前面&#xff0c;值较大的元素从前面移到后面。 大数据往上冒泡&#xff0c;小数据往下沉&#xff0c;也就是…

大语言模型垂直化训练技术与应用

在人工智能领域&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已经成为推动技术进步的关键力量&#xff0c;垂直化训练技术逐渐成为研究的热点&#xff0c;它使得大模型能够更精准地服务于特定行业和应用场景。本文结合达观数据的分享&#xff0c…

tomcat 项目迁移,无法将项目作为服务service启动

背景 测试服务器需要迁移到正式服务器上&#xff0c;为了方便省事&#xff0c;将测试服务器上的一些文件直接复制到正式服务器 问题 使用startup启动项目之后&#xff0c;可以直接使用使用tomcat9w启动&#xff0c;或者作为服务service启动的时候&#xff0c;显示无法访问到资源…

AGE Cypher 查询格式

使用 ag_catalog 中的名为 cypher 的函数构建 Cypher 查询&#xff0c;该函数返回 Postgres 的记录集合。 Cypher() Cypher() 函数执行作为参数传递的 Cypher 查询。 语法&#xff1a;cypher(graph_name, query_string, parameters) 返回&#xff1a; A SETOF records 参…

自动驾驶事故频发,安全痛点在哪里?

大数据产业创新服务媒体 ——聚焦数据 改变商业 近日&#xff0c;武汉城市留言板上出现了多条关于萝卜快跑的投诉&#xff0c;多名市民反映萝卜快跑出现无故停在马路中间、高架上占最左道低速行驶、转弯卡着不动等情况&#xff0c;导致早晚高峰时段出现拥堵。萝卜快跑是百度 A…

YOLOv5、v7、v8如何修改检测框文字颜色和大小

YOLOv5和YOLOv8默认的标签文字颜色为白色&#xff0c;但是在亮度较大的图片中文字不明显&#xff0c;就需要对标签文字的颜色进行修改 一、YOLOv5 打开X:\Anaconda\envs\your-env\Lib\site-packages\ultralytics\utils\plotting.py X代表你的anaconda安装的盘&#xff0c;yo…

随笔(一)

1.即时通信软件原理&#xff08;发展&#xff09; 即时通信软件实现原理_即时通讯原理-CSDN博客 笔记&#xff1a; 2.泛洪算法&#xff1a; 算法介绍 | 泛洪算法&#xff08;Flood fill Algorithm&#xff09;-CSDN博客 漫水填充算法实现最常见有四邻域像素填充法&#xf…

最全windows提权总结(建议收藏)

当以低权用户进去一个陌生的windows机器后&#xff0c;无论是提权还是后续做什么&#xff0c;第一步肯定要尽可能的搜集信息。知己知彼&#xff0c;才百战不殆。 常规信息搜集 systeminfo 查询系统信息hostname 主机名net user 查看用户信息netstat -ano|find "3389&quo…

论文 | Chain-of-Thought Prompting Elicits Reasoningin Large Language Models 思维链

这篇论文研究了如何通过生成一系列中间推理步骤&#xff08;即思维链&#xff09;来显著提高大型语言模型进行复杂推理的能力。论文展示了一种简单的方法&#xff0c;称为思维链提示&#xff0c;通过在提示中提供几个思维链示例来自然地激发这种推理能力。 主要发现&#xff1…

SDIO CMD 数据部分 CRC 计算规则

使用的在线 crc 计算工具网址&#xff1a;http://www.ip33.com/crc.html CMD CRC7 计算 如下图为使用逻辑分析仪获取的SDIO读写SD卡时&#xff0c;CMD16指令发送的格式&#xff0c;通过逻辑分析仪总线分析&#xff0c;可以看到&#xff0c;该部分的CRC7校验值得0x05,大多数情况…