建立试题库文件json
第一步:
按标准格式保存试题到本地,文件名为.json.
import json
import os
image_path = os.path.join('C:\\', 'Users', '123', 'PycharmProjects', 'pythonProject1', 'test01', 'imges', 'jxn_0900.png')
# 准备要保存的数据
data = [
{
"id": 1,
"question": "荡秋千的简化模型如图所示,摆球从A点由静止释放,到达D点后返回,B、C两点等高,下列说法正确的是:( )",
"image":os.path.join('C:\\', 'Users', '123', 'PycharmProjects', 'pythonProject1', 'test01', 'imges', 'jxn_0100.png'),
"options": ["球在B、C两点的动能相等", "球在A、D两点的机械能相等", "球从B点到O点的过程中机械能减少", "球从O点到C点的过程中重力势能减少"],
"answer": "C"
},
{
"id": 2,
"question": "在水平地面上铺一张白纸,将皮球表面涂黑,使其分别从不同高度处自由下落,在纸上留下黑色圆斑A、B,如图所示。下列说法中正确的是:( )",
"image":os.path.join('C:\\', 'Users', '123', 'PycharmProjects', 'pythonProject1', 'test01', 'imges', 'jxn_0200.png'),
"options": ["皮球下落过程中动能转化为重力势能", "皮球落地发生形变的过程中动能转化为弹性势能", "形成圆斑B时皮球是从更高处下落的", "形成圆斑A时皮球接触地面后形变程度更小"],
"answer":"B"
},
{
"id": 3,
"question": "太空之家再迎“新成员”,2023年5月30日,搭载神舟十六号载人飞船的长征二号F运载 火箭,在酒泉卫星发射中心点火升空,中国空间站全面建成后首次载人飞行任务开启。神州十六号飞船升空过程中,下列有关说法中正确的是:( )",
"image":os.path.join('C:\\', 'Users', '123', 'PycharmProjects', 'pythonProject1', 'test01', 'imges', 'jxn_0300.png'),
"options": ["航天员相对于地球是静止的", "航天员的重力势能保持不变", "航天员的惯性没有发生变化", "航天员的重力势能转化为动能"],
"answer": "C"
},
{
"id": 4,
"question": "小明和同学一起荡秋千。下列说法正确的是:( )",
"options": ["通过最低点时的动能为零", "下降过程中的动能不变", "到达最高点的重力势能最大", "上升过程中的重力势能减小"],
"image": os.path.join('C:\\', 'Users', '123', 'PycharmProjects', 'pythonProject1', 'test01', 'imges', 'jxn_0400.png'),
"answer": "C"
},
{
"id": 5,
"question": "如图所示,先用绳子把一个铁锁悬挂起来,然后把铁锁靠近到自己的鼻子,松手后,铁锁向前摆动又摆回来。若不考虑空气阻力与摩擦,有关铁锁在摆动过程中的能量转化,下列说法错误的是:( )",
"options": ["铁锁回摆不能碰到鼻子,因为铁锁的机械能始终不变", "铁锁下降过程中,重力势能转化为动能", "铁锁下降到最低点,动能最大", "铁锁上升到最高点,重力势能最小"],
"image": os.path.join('C:\\', 'Users', '123', 'PycharmProjects', 'pythonProject1', 'test01', 'imges', 'jxn_0500.png'),
"answer":"D"
},
{
"id": 6,
"question": "《清明上河图》中一个人正在荡秋千的场景,下列判断中正确的是?( )",
"options": ["运动到最高点时,她的动能为零,重力势能最大", "运动到最低点时,她的动能最大,没有重力势能", "从最高点到最低点的过程中,她的动能转化为重力势能", "在荡秋千的整个过程中,她的机械能的总和不变"],
"image": os.path.join('C:\\', 'Users', '123', 'PycharmProjects', 'pythonProject1', 'test01', 'imges', 'jxn_0600.png'),
"answer": "A"
},
{ "id": 7,
"question": "将石块从高处斜向上抛出,其运动过程如图所示,不计空气阻力,下列说法正确的是?",
"options": ["在最高点石块动能为零", "上升过程中的机械能大于下降过程中的机械能", "在上升过程中,重力势能转化为动能", "在空中运动的过程中,机械能守恒"],
"image": os.path.join('C:\\', 'Users', '123', 'PycharmProjects', 'pythonProject1', 'test01', 'imges', 'jxn_0700.png'),
"answer": "D"
},
{
"id": 8,
"question": "如图所示是一位勇敢的“蹦极”爱好者纵身跳下时的情景,a点是弹性绳自然下垂时绳下端的位置,b点是蹦极者速度最大的位置,c点是蹦极者下降的最低点,下列说法正确的是( )",
"options": ["蹦极者在a点的动能最大", "从a点到b点,蹦极者的重力势能转化为绳的弹性势能和蹦极者的动能", "在c点时,蹦极者的动能和重力势能为零,绳的弹性势能最大", "从a点到c点的过程中,整个系统的机械能增大"],
"image": os.path.join('C:\\', 'Users', '123', 'PycharmProjects', 'pythonProject1', 'test01', 'imges', 'jxn_0800.png'),
"answer": "B"
},
{ "id": 9,
"question": "游乐园里小朋友们在蹦床上欢欣跳跃,关于此过程中的有关现象,下列说法正确的是( )",
"options": ["小朋友与蹦床刚接触时,受到蹦床的弹力最大", "小朋友下落到最低点时受力平衡", "小朋友被蹦床反弹上升的过程中,既有动能又有重力势能", "小朋友从接触蹦床到最低点的过程中速度一直在减小"],
"image":os.path.join('C:\\', 'Users', '123', 'PycharmProjects', 'pythonProject1', 'test01', 'imges', 'jxn_0900.png'),
"answer": "C"
}
]
# 将数据写入 JSON 文件
with open('data.json', 'w') as f:
json.dump(data, f)
# 从 JSON 文件中读取数据
with open('data.json', 'r') as f:
read_data = json.load(f)
# 打印读取的数据
print(read_data)
第二步:建立试题对应图片文件
第三步、建立本地调用试题文件py
import json
import random
from PIL import Image
import os
import matplotlib.pyplot as plt
# 存储试题的文件名
QUESTIONS_FILE = 'data.json'
def load_wrong_questions(user_name):
# 检查用户的错题本文件是否存在,如果存在,则读取其中的试题
wrong_questions_file = f"{user_name}_wrong_questions.json"
if os.path.exists(wrong_questions_file):
with open(wrong_questions_file) as f:
wrong_questions = [json.loads(line) for line in f]
return wrong_questions
else:
return []
def load_questions(user_name):
# 读取题库
with open(QUESTIONS_FILE) as f:
questions = json.load(f)
# 获取错题本中的试题,并将其加入到试题中
wrong_questions = load_wrong_questions(user_name)
questions = wrong_questions + questions
# 统计每道试题的错误次数
wrong_counts = {}
for question in wrong_questions:
question_id = question['id']
if question_id not in wrong_counts:
wrong_counts[question_id] = 1
else:
wrong_counts[question_id] += 1
# 按照错误次数从多到少排序
sorted_questions = sorted(questions, key=lambda x: wrong_counts.get(x['id'], 0), reverse=True)
return sorted_questions
def ask_question(user_name, from_wrong=False, from_bank=False):
# 存储得分的文件名
scores_file = f"{user_name}_scores.json"
# 存储用户答错的试题的文件名
wrong_questions_file = f"{user_name}_wrong_questions.json"
# 获取试题
random_question = None # 初始化随机试题
if from_wrong:
# 从错题本中获取试题
wrong_questions = load_wrong_questions(user_name)
if wrong_questions:
random_question = random.choice(wrong_questions)
elif from_bank:
# 从题库中获取试题
questions = load_questions(user_name)
if questions:
random_question = random.choice(questions)
else:
# 根据上一次的加载方式选择加载试题
if os.path.exists(f"{user_name}_last_question_source.txt"):
with open(f"{user_name}_last_question_source.txt", 'r') as f:
last_question_source = f.read().strip()
if last_question_source == 'bank':
# 上一次加载的试题来自题库,本次加载的试题必须来源于错题本
if os.path.exists(f"{user_name}_wrong_questions.json"):
wrong_questions = load_wrong_questions(user_name)
if wrong_questions and len(wrong_questions) > 5:
random_question = random.choice(wrong_questions)
else:
pass
else:
# 上一次加载的试题来自错题本,询问用户想要继续加载题库还是练习错题
print("Which kind of questions do you want to practice?")
print("1. From wrong questions(从错题本载入).")
print("2. From questions bank(从试题库载入).")
choice = input("Please select: ").strip()
while choice not in ['1', '2']:
print("Invalid choice, please try again.")
choice = input("Please select: ").strip()
if choice == '1':
# 练习错题
if os.path.exists(f"{user_name}_wrong_questions.json"):
wrong_questions = load_wrong_questions(user_name)
if wrong_questions and len(wrong_questions) > 5:
random_question = random.choice(wrong_questions)
else:
pass
else:
# 练习题库中的试题
questions = load_questions(user_name)
if questions:
random_question = random.choice(questions)
else:
# 第一次加载试题,从题库中获取试题
questions = load_questions(user_name)
if questions:
random_question = random.choice(questions)
if random_question:
# 保存本次加载试题的来源到文件,以备下一次加载试题时使用
with open(f"{user_name}_last_question_source.txt", 'w') as f:
f.write("bank" if from_bank else "wrong")
# 提示用户回答问题
print(random_question['question'])
for i, option in enumerate(random_question['options']):
letter = chr(i + ord('A')) # 将数字转换为字母
print(f"{letter}. {option}")
# 加载图片并显示
if 'image' in random_question:
image_path = os.path.join(os.path.dirname(QUESTIONS_FILE), random_question['image'])
image = Image.open(image_path)
plt.imshow(image, interpolation='nearest') # 设置interpolation参数为'nearest'
plt.axis('off') # 关闭坐标轴
plt.show()
# 获取用户回答
selected_option = input("Your answer: ").strip().lower() # 转换为小写字母,删除开头和结尾的空白字符
# 验证用户回答是否正确
correct_option = random_question['answer'].lower() # 将正确答案也转换为小写字母
if selected_option == correct_option:
print("Correct!")
else:
print("Wrong.")
# 保存用户答错的试题到错题本文件
with open(wrong_questions_file, 'a') as f:
f.write(json.dumps(random_question) + '\n')
# 保存得分
score = 100 if selected_option == correct_option else 0
with open(scores_file, 'a') as f:
f.write(f"{score}\n")
# 在错题本中删除答对的试题
if from_wrong and selected_option == correct_option:
wrong_questions = load_wrong_questions(user_name)
if wrong_questions:
wrong_questions = [q for q in wrong_questions if q['id'] != random_question['id']]
with open(wrong_questions_file, 'w') as f:
for question in wrong_questions:
f.write(json.dumps(question) + '\n')
else:
print("Failed to get random question.")
def start_practice(user_name):
# 循环调用试题
count = 3 # 初始化计数器
while True:
ask_question(user_name)
count -= 1
if count == 0:
# 每做3道题后询问用户是否继续做题
if len(load_wrong_questions(user_name)) > 5:
ask_again = input("Do you want to continue? (y/n)").strip().lower()
if ask_again != 'y':
break
else:
count = 3 # 重置计数器
else:
print("Wrong questions less than 5,continue to choose from bank.")
count = 3 # 重置计数器
if __name__ == '__main__':
# 获取用户名称
user_name = input("Please input your name: ").strip()
while not user_name:
# 如果用户名称为空,则提示用户重新输入
print("User name cannot be empty, please try again.")
user_name = input("Please input your name: ").strip()
# 开始练习
start_practice(user_name)