MisConceptTutor / app.py
Jintonic92's picture
Update app.py
0a8c581 verified
raw
history blame
6.67 kB
import streamlit as st
import pandas as pd
import os
import logging
from src.SecondModule.module2 import SimilarQuestionGenerator, generate_similar_question
# λ‘œκΉ… μ„€μ •
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Streamlit νŽ˜μ΄μ§€ κΈ°λ³Έ μ„€μ •
st.set_page_config(
page_title="MisconcepTutor",
layout="wide",
initial_sidebar_state="expanded"
)
# 경둜 μ„€μ •
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')
# μ„Έμ…˜ μƒνƒœ μ΄ˆκΈ°ν™”
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")
# 문제 생성기 μ΄ˆκΈ°ν™”
@st.cache_resource
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 데이터 λ‘œλ“œ
@st.cache_data
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'
# 메인 μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 둜직
def main():
st.title("MisconcepTutor")
generator = load_question_generator()
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("---")
st.write(current_q['QuestionText'])
col1, col2 = st.columns(2)
with col1:
if st.button(f"A) {current_q['AnswerAText']}", key="A"):
handle_answer('A', current_q)
st.rerun()
if st.button(f"C) {current_q['AnswerCText']}", key="C"):
handle_answer('C', current_q)
st.rerun()
with col2:
if st.button(f"B) {current_q['AnswerBText']}", key="B"):
handle_answer('B', current_q)
st.rerun()
if st.button(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 len(st.session_state.wrong_questions) == 0:
st.balloons()
st.success("πŸŽ‰ λͺ¨λ“  문제λ₯Ό λ§žμΆ”μ…¨μŠ΅λ‹ˆλ‹€!")
elif len(st.session_state.wrong_questions) <= 3:
st.success("잘 ν•˜μ…¨μ–΄μš”! 쑰금만 더 μ—°μŠ΅ν•˜λ©΄ μ™„λ²½ν•΄μ§ˆ κ±°μ˜ˆμš”!")
else:
st.info("천천히 κ°œλ…μ„ λ³΅μŠ΅ν•΄ λ³΄μ„Έμš”. μ—°μŠ΅ν•˜λ©΄ λ‚˜μ•„μ§ˆ κ²λ‹ˆλ‹€.")
if st.session_state.wrong_questions:
st.write("### ✍️ ν‹€λ¦° 문제 뢄석")
for i, (wrong_q, misconception_id) in enumerate(zip(
st.session_state.wrong_questions, st.session_state.misconceptions
)):
with st.expander(f"πŸ“ ν‹€λ¦° 문제 #{i + 1}"):
st.write(wrong_q['QuestionText'])
st.write(f"βœ… μ •λ‹΅: {wrong_q['CorrectAnswer']}")
if misconception_id:
misconception_text = generator.get_misconception_text(misconception_id)
st.info(f"Misconception: {misconception_text}")
if st.button(f"πŸ“š μœ μ‚¬ 문제 ν’€κΈ° #{i + 1}", key=f"retry_{i}"):
new_question = generate_similar_question(wrong_q, misconception_id, generator)
if new_question:
st.write("### 🎯 μœ μ‚¬ 문제")
st.write(new_question['question'])
for choice, text in new_question['choices'].items():
st.write(f"{choice}) {text}")
st.write(f"βœ… μ •λ‹΅: {new_question['correct']}")
st.write(f"πŸ“ ν•΄μ„€: {new_question['explanation']}")
else:
st.error("μœ μ‚¬ 문제λ₯Ό 생성할 수 μ—†μŠ΅λ‹ˆλ‹€.")
if __name__ == "__main__":
main()