import sqlite3 import streamlit as st import random import time from datetime import datetime, timedelta class QuizApp: def __init__(self): self.conn = sqlite3.connect('exam.db') self.cursor = self.conn.cursor() self.initialize_session_state() def fetch_questions(self, year, trial, paper_id): self.cursor.execute(''' SELECT question_id, question, option_A, option_B, option_C, option_D, answer FROM exam_questions WHERE year = ? AND trial = ? AND id = ? ''', (year, trial, paper_id)) questions = self.cursor.fetchall() return questions def initialize_session_state(self): if 'questions' not in st.session_state: st.session_state['questions'] = [] if 'user_answers' not in st.session_state: st.session_state['user_answers'] = {} if 'current_question_index' not in st.session_state: st.session_state['current_question_index'] = 0 if 'start_time' not in st.session_state: st.session_state['start_time'] = time.time() if 'quiz_ended' not in st.session_state: st.session_state['quiz_ended'] = False if 'score' not in st.session_state: st.session_state['score'] = 0 if 'wrong_answers' not in st.session_state: st.session_state['wrong_answers'] = [] if 'quiz_started' not in st.session_state: st.session_state['quiz_started'] = False if 'end_time' not in st.session_state: st.session_state['end_time'] = datetime.now() + timedelta(minutes=120) if 'question_order' not in st.session_state: st.session_state['question_order'] = [] def extract_image_url(self, question_text): img_tag_start = '', '') return question, options_text, options, selected_option, image_url def submit_answer(self, selected_option): question_id = st.session_state['questions'][st.session_state['current_question_index']][0] st.session_state['user_answers'][question_id] = selected_option def next_question(self): if st.session_state['current_question_index'] < len(st.session_state['questions'])-1: st.session_state['current_question_index']+=1 else: self.end_quiz() def end_quiz(self): score = 0 wrong_answers = [] for question in st.session_state['questions']: question_id, _, _, _, _, _, correct_answer = question if str(st.session_state['user_answers'].get(question_id)) == correct_answer: score+=1 else: wrong_answers.append((question_id, correct_answer)) st.session_state['score'] = score st.session_state['wrong_answers'] = sorted(wrong_answers, key=lambda x: int(x[0])) st.session_state['quiz_ended'] = True def render_quiz(self): timer_placeholder = st.empty() if not st.session_state['quiz_ended']: question, options_text, options, selected_option, image_url = self.show_question(st.session_state['current_question_index']) st.write(f"{st.session_state['current_question_index']+1}. {question}") if image_url: st.image(image_url) # Ensure form submission logic is handled correctly with st.form(key="quiz_form"): selected_option_text = st.radio("Choose an option", options_text, index=options_text.index(selected_option) if selected_option else 0) submit_button = st.form_submit_button(label="Submit Answer") if submit_button: selected_option = options[options_text.index(selected_option_text)] print(selected_option, selected_option_text) self.submit_answer(selected_option) self.next_question() st.experimental_rerun() st.button("End Quiz", on_click=self.end_quiz) # Dynamic countdown timer remaining_time = st.session_state['end_time'] - datetime.now() if remaining_time.total_seconds()>0: minutes, seconds = divmod(remaining_time.total_seconds(), 60) timer_placeholder.markdown(f"## 剩餘時間: {int(minutes):02d}:{int(seconds):02d}") time.sleep(1) st.experimental_rerun() else: self.end_quiz() else: st.write(f"Score: {st.session_state['score']}/{len(st.session_state['questions'])}") selected_id = st.selectbox("Select Question to View Details", range(1, len(st.session_state['questions'])+1)) if selected_id-1 is not None: question = st.session_state['questions'][selected_id-1] st.write(f"試卷題號: {question[0]}") st.write(f"{question[1]}") st.write(f"A. {question[2]}") st.write(f"B. {question[3]}") st.write(f"C. {question[4]}") st.write(f"D. {question[5]}") st.write(f"答案: {question[6]}") def render(self): if not st.session_state['quiz_started']: st.title("考古題選擇") year = st.selectbox("年份", ['111', '112', '113']) trial = st.selectbox("場次", ("寒考", "暑考")) paper_id = st.selectbox("考卷", ("醫師(一)", "醫師(二)")) if st.button("Submit"): if trial == "寒考": trial_q = 1 else: trial_q = 2 if paper_id == "醫師(一)": id_q = 1 else: id_q = 2 st.session_state['questions'] = self.fetch_questions(year, trial_q, id_q) if st.session_state['questions']: random.shuffle(st.session_state['questions']) st.session_state['question_order'] = [q[0] for q in st.session_state['questions']] st.session_state['quiz_started'] = True st.session_state['end_time'] = datetime.now()+timedelta(minutes=120) st.experimental_rerun() else: st.write("找不到對應的考卷,請重新選擇。") else: self.render_quiz() if __name__ == "__main__": app = QuizApp() app.render()