CommTutor / file_study_guide_panel.py
ankban's picture
Update file_study_guide_panel.py
3316153 verified
Raw
History Blame Contribute Delete
6.1 kB
import gradio as gr
import json
from file_utils import extract_text_from_file, call_llm, save_study_guide, fetch_study_guides
def file_study_guide_dashboard(nickname_input):
with gr.Column() as panel:
file_input = gr.File(label="πŸ“€ Upload a File", file_types=[".pdf", ".txt", ".md", ".pptx"])
save_btn = gr.Button("πŸ’Ύ Save Guide")
guide_dropdown = gr.Dropdown(label="πŸ“š Your Saved Guides", choices=[])
section_output = gr.Column()
file_text_state = gr.State("")
guide_state = gr.State([])
def sample_section():
return render_sections([{
"section_title": "Sample Section",
"overview": "This is a short summary of the topic.",
"explanation": "This is a detailed explanation to show how learning content will look.",
"quiz": [
{"question": "What is 2+2?", "options": ["1", "2", "3", "4"], "answer": "4"},
{"question": "Sample Q2?", "options": ["A", "B", "C", "D"], "answer": "B"},
{"question": "Sample Q3?", "options": ["A", "B", "C", "D"], "answer": "C"},
{"question": "Sample Q4?", "options": ["A", "B", "C", "D"], "answer": "D"},
{"question": "Sample Q5?", "options": ["A", "B", "C", "D"], "answer": "A"}
]
}])
# Move this after render_sections is defined
pass
def generate_study_guide(file):
if file is None:
return [gr.Markdown("❌ No file uploaded.")], "", []
text = extract_text_from_file(file)
prompt = f"""
You are an AI tutor. Divide the following content into 5–6 logical sections.
For each section:
- Provide a 2–3 line summary (overview)
- Write a detailed explanation of the topic
- Create 5 multiple choice questions (MCQs), each with:
- A question
- 4 options
- 1 correct answer
Return as JSON in this format:
[
{{
"section_title": "...",
"overview": "...",
"explanation": "...",
"quiz": [
{{"question": "...", "options": ["A", "B", "C", "D"], "answer": "B"}},
...
]
}},
...
]
Text:
{text}
"""
response = call_llm(prompt)
try:
guide = json.loads(response)
section_output.children = render_sections(guide)
return text, guide
except:
section_output.children = [gr.Markdown("❌ Failed to parse structured study guide.")]
return text, []
def render_sections(guide_data):
blocks = []
for i, sec in enumerate(guide_data):
blocks.append(render_section(i + 1, sec))
return blocks
def render_section(index, sec):
block = gr.Column()
with block:
gr.Markdown(f"## πŸ“˜ Section {index}: {sec['section_title']}")
gr.Markdown(f"**Overview:** {sec['overview']}")
gr.Markdown(f"**Explanation:**\n\n{sec['explanation']}")
gr.Markdown("### 🧠 Quiz")
question_area = gr.Column()
def make_question_ui(q_idx):
q = sec['quiz'][q_idx]
q_box = gr.Markdown(f"**Q{q_idx+1}.** {q['question']}")
q_radio = gr.Radio(q['options'], label="Choose an answer")
def grade(choice):
correct = q['answer']
return "βœ… Correct!" if choice == correct else f"❌ Correct: {correct}"
q_radio.change(fn=grade, inputs=[q_radio], outputs=[feedback_box])
return [q_box, q_radio]
feedback_box = gr.Textbox(label="Answer Feedback", interactive=False)
question_area.children = make_question_ui(0)
with gr.Row():
for i in range(5):
gr.Button(str(i + 1), size="sm").click(fn=lambda idx=i: make_question_ui(idx), inputs=[], outputs=question_area)
return block
def save_to_user(nickname, filename, guide):
if not guide or not filename:
return
save_study_guide(nickname, filename.name, json.dumps(guide))
def load_user_guides(user):
guides = fetch_study_guides(user)
return [f"{g.filename} ({g.timestamp})" for g in guides]
# Initialize with sample content after all functions are defined
section_output.children = render_sections([{
"section_title": "Sample Section",
"overview": "This is a short summary of the topic.",
"explanation": "This is a detailed explanation to show how learning content will look.",
"quiz": [
{"question": "What is 2+2?", "options": ["1", "2", "3", "4"], "answer": "4"},
{"question": "Sample Q2?", "options": ["A", "B", "C", "D"], "answer": "B"},
{"question": "Sample Q3?", "options": ["A", "B", "C", "D"], "answer": "C"},
{"question": "Sample Q4?", "options": ["A", "B", "C", "D"], "answer": "D"},
{"question": "Sample Q5?", "options": ["A", "B", "C", "D"], "answer": "A"}
]
}])
def show_saved_guide(user, label):
guides = fetch_study_guides(user)
for g in guides:
if label.startswith(g.filename):
section_output.children = render_sections(json.loads(g.guide))
return
section_output.children = [gr.Markdown("❌ Guide not found.")]
file_input.change(fn=generate_study_guide, inputs=[file_input], outputs=[file_text_state, guide_state])
save_btn.click(fn=save_to_user, inputs=[nickname_input, file_input, guide_state], outputs=[])
nickname_input.change(fn=load_user_guides, inputs=[nickname_input], outputs=[guide_dropdown])
guide_dropdown.change(fn=show_saved_guide, inputs=[nickname_input, guide_dropdown], outputs=[])
return panel