Spaces:
Sleeping
Sleeping
Download app.py from HaileyIsNotAPig/SE_MED_I: direct link, hf CLI and curl.
- Browser
- Download file 7.36 kB
-
https://huggingface.co/spaces/HaileyIsNotAPig/SE_MED_I/resolve/main/app.py
- Command line
-
hf download hf://spaces/HaileyIsNotAPig/SE_MED_I/app.py
-
curl -L -o app.py https://huggingface.co/spaces/HaileyIsNotAPig/SE_MED_I/resolve/main/app.py
7.36 kB
| 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 = '<img src="' | |
| img_tag_end = '"' | |
| start_index = question_text.find(img_tag_start) | |
| if start_index != -1: | |
| end_index = question_text.find(img_tag_end, start_index+len(img_tag_start)) | |
| if end_index != -1: | |
| return question_text[start_index+len(img_tag_start):end_index] | |
| return None | |
| def show_question(self, index): | |
| question_id, question, option_A, option_B, option_C, option_D, _ = st.session_state['questions'][index] | |
| options = ['A', 'B', 'C', 'D'] | |
| options_text = [option_A, option_B, option_C, option_D] | |
| selected_option = st.session_state['user_answers'].get(question_id, None) | |
| image_url = self.extract_image_url(question) | |
| if image_url: | |
| question = question.replace(f'<img src="{image_url}" />', '') | |
| 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() | |