Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import pandas as pd | |
| import os | |
| from src.FisrtModule.module1 import MisconceptionModel | |
| from src.SecondModule.module2 import SimilarQuestionGenerator | |
| from src.ThirdModule.module3 import AnswerVerifier | |
| import logging | |
| from typing import Optional, Tuple | |
| from latex_formatter import LatexFormatter | |
| logging.basicConfig(level=logging.DEBUG) | |
| # Initialize Misconception Model | |
| def load_misconception_model(): | |
| return MisconceptionModel( | |
| model_name="minsuas/Misconceptions__1", | |
| misconception_mapping_path=os.path.join(data_path, 'misconception_mapping.parquet'), | |
| misconception_embs_paths=[os.path.join(data_path, f'embs_misconception-9.npy')] | |
| ) | |
| # Streamlit ํ์ด์ง ๊ธฐ๋ณธ ์ค์ | |
| st.set_page_config( | |
| page_title="MisconcepTutor", | |
| layout="wide", | |
| initial_sidebar_state="expanded" | |
| ) | |
| def load_answer_verifier(): | |
| """๋ต์ ๊ฒ์ฆ ๋ชจ๋ธ ๋ก๋""" | |
| from src.ThirdModule.module3 import AnswerVerifier | |
| return AnswerVerifier() | |
| # ๊ฒฝ๋ก ์ค์ | |
| base_path = os.path.dirname(os.path.abspath(__file__)) | |
| data_path = os.path.join(base_path, 'Data') | |
| misconception_csv_path = os.path.join(data_path, 'misconception_mapping.csv') | |
| # ๋ก๊น ์ค์ | |
| logging.basicConfig(level=logging.INFO) | |
| logger = logging.getLogger(__name__) | |
| # ์ธ์ ์ํ ์ด๊ธฐํ | |
| if 'initialized' not in st.session_state: | |
| st.session_state.initialized = True | |
| st.session_state.wrong_questions = [] | |
| st.session_state.misconceptions = [] | |
| st.session_state.current_question_index = 0 | |
| st.session_state.generated_questions = [] | |
| st.session_state.current_step = 'initial' | |
| st.session_state.selected_wrong_answer = None | |
| st.session_state.questions = [] | |
| logger.info("Session state initialized") | |
| # ๋ฌธ์ ์์ฑ๊ธฐ ์ด๊ธฐํ | |
| def load_question_generator(): | |
| """๋ฌธ์ ์์ฑ ๋ชจ๋ธ ๋ก๋""" | |
| if not os.path.exists(misconception_csv_path): | |
| st.error(f"CSV ํ์ผ์ด ์กด์ฌํ์ง ์์ต๋๋ค: {misconception_csv_path}") | |
| raise FileNotFoundError(f"CSV ํ์ผ์ด ์กด์ฌํ์ง ์์ต๋๋ค: {misconception_csv_path}") | |
| return SimilarQuestionGenerator(misconception_csv_path=misconception_csv_path) | |
| # CSV ๋ฐ์ดํฐ ๋ก๋ ํจ์ | |
| def load_data(data_file='/train.csv'): | |
| try: | |
| file_path = os.path.join(data_path, data_file.lstrip('/')) | |
| df = pd.read_csv(file_path) | |
| logger.info(f"Data loaded successfully from {file_path}") | |
| return df | |
| except FileNotFoundError: | |
| st.error(f"ํ์ผ์ ์ฐพ์ ์ ์์ต๋๋ค: {data_file}") | |
| logger.error(f"File not found: {data_file}") | |
| return None | |
| def start_quiz(): | |
| """ํด์ฆ ์์ ๋ฐ ์ด๊ธฐํ""" | |
| df = load_data() | |
| if df is None or df.empty: | |
| st.error("๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฌ์ฌ ์ ์์ต๋๋ค. ๋ฐ์ดํฐ์ ์ ํ์ธํด์ฃผ์ธ์.") | |
| return | |
| st.session_state.questions = df.sample(n=10, random_state=42) | |
| st.session_state.current_step = 'quiz' | |
| st.session_state.current_question_index = 0 | |
| st.session_state.wrong_questions = [] | |
| st.session_state.misconceptions = [] | |
| st.session_state.generated_questions = [] | |
| logger.info("Quiz started") | |
| def handle_answer(answer, current_q): | |
| """๋ต๋ณ ์ฒ๋ฆฌ""" | |
| if answer != current_q['CorrectAnswer']: | |
| wrong_q_dict = current_q.to_dict() | |
| st.session_state.wrong_questions.append(wrong_q_dict) | |
| st.session_state.selected_wrong_answer = answer | |
| misconception_key = f'Misconception{answer}Id' | |
| misconception_id = current_q.get(misconception_key) | |
| st.session_state.misconceptions.append(misconception_id) | |
| st.session_state.current_question_index += 1 | |
| if st.session_state.current_question_index >= 10: | |
| st.session_state.current_step = 'review' | |
| # ์ ์ญ LaTeX ํฌ๋งทํฐ ์ธ์คํด์ค ์์ฑ | |
| latex_formatter = LatexFormatter() | |
| def display_math_content(content: str): | |
| """์ํ ๋ด์ฉ์ ํ๋ฉด์ ํ์""" | |
| formatted_content = latex_formatter.format_expression(content) | |
| st.markdown(formatted_content, unsafe_allow_html=True) | |
| def main(): | |
| """๋ฉ์ธ ์ ํ๋ฆฌ์ผ์ด์ ๋ก์ง""" | |
| st.title("MisconcepTutor") | |
| # Misconception Model ๋ก๋ | |
| misconception_model = load_misconception_model() | |
| # ์ด๊ธฐ ํ๋ฉด | |
| if st.session_state.current_step == 'initial': | |
| st.write("#### ํ์ต์ ์์ํ๊ฒ ์ต๋๋ค. 10๊ฐ์ ๋ฌธ์ ๋ฅผ ํ์ด๋ณผ๊น์?") | |
| if st.button("ํ์ต ์์", key="start_quiz"): | |
| start_quiz() | |
| st.rerun() | |
| # ํด์ฆ ํ๋ฉด | |
| elif st.session_state.current_step == 'quiz': | |
| current_q = st.session_state.questions.iloc[st.session_state.current_question_index] | |
| # ์งํ ์ํฉ ํ์ | |
| progress = st.session_state.current_question_index / 10 | |
| st.progress(progress) | |
| st.write(f"### ๋ฌธ์ {st.session_state.current_question_index + 1}/10") | |
| # ๋ฌธ์ ํ์ | |
| st.markdown("---") | |
| display_math_content(current_q['QuestionText']) | |
| # ๋ณด๊ธฐ ํ์ | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| if st.button(latex_formatter.format_expression(f"A) {current_q['AnswerAText']}"), key="A"): | |
| handle_answer('A', current_q) | |
| st.rerun() | |
| if st.button(latex_formatter.format_expression(f"C) {current_q['AnswerCText']}"), key="C"): | |
| handle_answer('C', current_q) | |
| st.rerun() | |
| with col2: | |
| if st.button(latex_formatter.format_expression(f"B) {current_q['AnswerBText']}"), key="B"): | |
| handle_answer('B', current_q) | |
| st.rerun() | |
| if st.button(latex_formatter.format_expression(f"D) {current_q['AnswerDText']}"), key="D"): | |
| handle_answer('D', current_q) | |
| st.rerun() | |
| # ๋ณต์ต ํ๋ฉด | |
| elif st.session_state.current_step == 'review': | |
| st.write("### ํ์ต ๊ฒฐ๊ณผ") | |
| # ๊ฒฐ๊ณผ ํต๊ณ | |
| col1, col2, col3 = st.columns(3) | |
| col1.metric("์ด ๋ฌธ์ ์", 10) | |
| col2.metric("๋ง์ ๋ฌธ์ ", 10 - len(st.session_state.wrong_questions)) | |
| col3.metric("ํ๋ฆฐ ๋ฌธ์ ", len(st.session_state.wrong_questions)) | |
| # ํ๋ฆฐ ๋ฌธ์ ๋ถ์ | |
| if st.session_state.wrong_questions: | |
| st.write("### โ๏ธ ํ๋ฆฐ ๋ฌธ์ ๋ถ์") | |
| tabs = st.tabs([f"๐ ํ๋ฆฐ ๋ฌธ์ #{i + 1}" for i in range(len(st.session_state.wrong_questions))]) | |
| for i, (tab, (wrong_q, misconception_id)) in enumerate(zip( | |
| tabs, | |
| zip(st.session_state.wrong_questions, st.session_state.misconceptions) | |
| )): | |
| with tab: | |
| st.write("**๐ ๋ฌธ์ :**") | |
| st.write(wrong_q['QuestionText']) | |
| st.write("**โ ์ ๋ต:**", wrong_q['CorrectAnswer']) | |
| st.write("---") | |
| st.write("**๐ ๊ด๋ จ๋ Misconception:**") | |
| if misconception_id and not pd.isna(misconception_id): | |
| misconception_text = misconception_model.misconception_names.get(misconception_id, "์ ๋ณด ์์") | |
| st.info(f"Misconception ID: {int(misconception_id)}\n\n{misconception_text}") | |
| else: | |
| st.info("Misconception ์ ๋ณด๊ฐ ์์ต๋๋ค.") | |
| if __name__ == "__main__": | |
| main() | |