新增错题记录功能,错题出现的频率会更高
This commit is contained in:
parent
b37063d4f0
commit
2985fb833e
1
.gitignore
vendored
1
.gitignore
vendored
@ -160,3 +160,4 @@ cython_debug/
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
/*.dat
|
||||
|
6
Config.py
Normal file
6
Config.py
Normal file
@ -0,0 +1,6 @@
|
||||
# 配置考卷
|
||||
quest_config = {
|
||||
'A': {'num': 30, 'time': 40, 'pass': 25},
|
||||
'B': {'num': 50, 'time': 60, 'pass': 40},
|
||||
'C': {'num': 80, 'time': 90, 'pass': 60}
|
||||
}
|
65
Generator.py
Normal file
65
Generator.py
Normal file
@ -0,0 +1,65 @@
|
||||
import json
|
||||
import os
|
||||
import random
|
||||
import Config
|
||||
|
||||
class Quest:
|
||||
def __init__(self, json_obj):
|
||||
self.index = json_obj['index']
|
||||
self.question = json_obj['Q']
|
||||
self.code = json_obj['I']
|
||||
self.correct = json_obj['A']
|
||||
self.options = [json_obj['A'], json_obj['B'], json_obj['C'], json_obj['D']]
|
||||
self.random_options = random.sample(self.options, len(self.options))
|
||||
|
||||
weight_path = 'weight.dat'
|
||||
|
||||
def enhance_weight(quest: Quest):
|
||||
with open(weight_path, 'r') as f:
|
||||
weight = json.load(f)
|
||||
if quest.code in weight:
|
||||
weight[quest.code] += 10
|
||||
else:
|
||||
weight[quest.code] = 10
|
||||
with open(weight_path, 'w') as f:
|
||||
json.dump(weight, f, ensure_ascii=False, indent=4)
|
||||
pass
|
||||
|
||||
def reduce_weight(quest: Quest):
|
||||
with open(weight_path, 'r') as f:
|
||||
weight = json.load(f)
|
||||
if quest.code in weight:
|
||||
weight[quest.code] -= 1
|
||||
else:
|
||||
weight[quest.code] = -1
|
||||
with open(weight_path, 'w') as f:
|
||||
json.dump(weight, f, ensure_ascii=False, indent=4)
|
||||
pass
|
||||
|
||||
# 模拟加载题目
|
||||
def generate_quests(type_str):
|
||||
# 模拟从JSON文件加载题目
|
||||
with open(f'quests/quests_{type_str}.json', 'r', encoding='utf-8') as f:
|
||||
json_content = json.load(f)
|
||||
list_quest = [Quest(obj) for obj in json_content]
|
||||
# load weight
|
||||
weights = {}
|
||||
if not os.path.exists(weight_path):
|
||||
with open(weight_path, 'w') as f:
|
||||
json.dump({}, f)
|
||||
else:
|
||||
with open(weight_path, 'r') as f:
|
||||
weights = json.load(f)
|
||||
# 将 list_quest 分为有权重和无权重的两部分
|
||||
list_quest_weighted = [quest for quest in list_quest if quest.code in weights]
|
||||
list_quest_unweighted = [quest for quest in list_quest if quest.code not in weights]
|
||||
# 有权中的按权重排序
|
||||
list_quest_weighted.sort(key=lambda x: weights[x.code], reverse=True)
|
||||
list_quest = list_quest_unweighted + list_quest_weighted
|
||||
# 根据权重随机选取题目 80% 的题目来自权重前 40% 的题目 20% 的题目来自权重后 60% 的题目
|
||||
num = Config.quest_config[type_str]['num'] # 要生成的题目数量
|
||||
top = int(num * 0.8)
|
||||
quests = random.sample(list_quest[:top], top) + random.sample(list_quest[top:], num - top)
|
||||
# 对 quests 中的题目再次随机排序
|
||||
random.shuffle(quests)
|
||||
return quests
|
59
Quest.py
59
Quest.py
@ -3,41 +3,13 @@ Quest.py
|
||||
"""
|
||||
import os
|
||||
import tkinter as tk
|
||||
import random
|
||||
import json
|
||||
import time
|
||||
import Generator
|
||||
import Config
|
||||
|
||||
# 配置考卷
|
||||
quest_config = {
|
||||
'A': {'num': 30, 'time': 40, 'pass': 25},
|
||||
'B': {'num': 50, 'time': 60, 'pass': 40},
|
||||
'C': {'num': 80, 'time': 90, 'pass': 60}
|
||||
}
|
||||
|
||||
font = ('Microsoft YaHei', 13)
|
||||
|
||||
|
||||
# 模拟加载题目
|
||||
def generate_quests(type_str):
|
||||
# 模拟从JSON文件加载题目
|
||||
with open(f'quests/quests_{type_str}.json', 'r', encoding='utf-8') as f:
|
||||
json_content = json.load(f)
|
||||
list_quest = []
|
||||
for obj in json_content:
|
||||
list_quest.append(Quest(obj))
|
||||
return random.sample(list_quest, quest_config[type_str]['num'])
|
||||
|
||||
|
||||
class Quest:
|
||||
def __init__(self, json_obj):
|
||||
self.index = json_obj['index']
|
||||
self.question = json_obj['Q']
|
||||
self.code = json_obj['I']
|
||||
self.correct = json_obj['A']
|
||||
self.options = [json_obj['A'], json_obj['B'], json_obj['C'], json_obj['D']]
|
||||
self.random_options = random.sample(self.options, len(self.options))
|
||||
|
||||
|
||||
class ExamApp:
|
||||
def __init__(self, root):
|
||||
self.next_btn = None
|
||||
@ -70,8 +42,8 @@ class ExamApp:
|
||||
|
||||
def start_exam(self, level):
|
||||
self.level = level
|
||||
self.time_left = quest_config[level]['time'] * 60 # 转换为秒
|
||||
self.quests = generate_quests(level)
|
||||
self.time_left = Config.quest_config[level]['time'] * 60 # 转换为秒
|
||||
self.quests = Generator.generate_quests(level)
|
||||
self.current_quest_index = 0
|
||||
self.selected_answers = {i: None for i in range(len(self.quests))}
|
||||
self.is_submitted = False
|
||||
@ -151,6 +123,7 @@ class ExamApp:
|
||||
else:
|
||||
# 显示正确答案
|
||||
self.correct_answer_label.config(text=f"正确答案: \n{quest.correct}")
|
||||
self.update_nav_buttons()
|
||||
|
||||
if self.current_quest_index == 0:
|
||||
self.prev_btn.config(state=tk.DISABLED)
|
||||
@ -167,13 +140,23 @@ class ExamApp:
|
||||
if not self.is_submitted:
|
||||
for i in range(len(self.quests)):
|
||||
color = "yellow" if self.selected_answers[i] else "white"
|
||||
if self.current_quest_index == i:
|
||||
color = "gray"
|
||||
btn = tk.Button(self.ques_nav_frame, text=f"{i + 1}", bg=color,
|
||||
command=lambda idx=i: self.jump_to_question(idx))
|
||||
btn.grid(row=i // 8, column=i % 8, sticky="nsew")
|
||||
else:
|
||||
for i in range(len(self.quests)):
|
||||
quest = self.quests[i]
|
||||
color = "green" if self.selected_answers[i] == quest.correct else "red"
|
||||
# color = "green" if self.selected_answers[i] == quest.correct else "red"
|
||||
color = "green"
|
||||
if self.selected_answers[i] != quest.correct:
|
||||
color = "red"
|
||||
if self.current_quest_index == i:
|
||||
if color == "green":
|
||||
color = "dark green"
|
||||
else:
|
||||
color = "dark red"
|
||||
btn = tk.Button(self.ques_nav_frame, text=f"{i + 1}", bg=color,
|
||||
command=lambda idx=i: self.jump_to_question(idx))
|
||||
btn.grid(row=i // 8, column=i % 8, sticky="nsew")
|
||||
@ -190,9 +173,15 @@ class ExamApp:
|
||||
self.is_submitted = True
|
||||
self.update_question()
|
||||
self.update_nav_buttons()
|
||||
correct_count = sum(1 for i, quest in enumerate(self.quests) if self.selected_answers[i] == quest.correct)
|
||||
correct_count = 0
|
||||
for i, quest in enumerate(self.quests):
|
||||
if self.selected_answers[i] == quest.correct:
|
||||
correct_count += 1
|
||||
Generator.reduce_weight(quest)
|
||||
else:
|
||||
Generator.enhance_weight(quest)
|
||||
|
||||
pass_score = quest_config[self.level]['pass']
|
||||
pass_score = Config.quest_config[self.level]['pass']
|
||||
result_text = "通过" if correct_count >= pass_score else "未通过"
|
||||
|
||||
self.timer_score_label.config(text=f"得分: {correct_count}/{len(self.quests)} - {result_text}")
|
||||
|
Loading…
Reference in New Issue
Block a user