Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import json | |
| from openai_llm import LessonPlanGenerator | |
| # Page configuration | |
| st.set_page_config( | |
| page_title="WizLab Lesson Plan Generator", | |
| page_icon="📚", | |
| layout="wide" | |
| ) | |
| # Custom CSS with improved styling | |
| st.markdown(""" | |
| <style> | |
| .main-container { | |
| background-color: white; | |
| border-radius: 8px; | |
| padding: 25px; | |
| margin: 20px 0; | |
| box-shadow: 0 2px 8px rgba(0,0,0,0.1); | |
| } | |
| .section { | |
| margin: 15px 0; | |
| padding: 10px 0; | |
| } | |
| .section-level-0 { | |
| border-bottom: 2px solid #e8eaf6; | |
| margin-bottom: 20px; | |
| } | |
| .section-level-1 { | |
| margin-left: 20px; | |
| border-left: 2px solid #e8eaf6; | |
| padding-left: 15px; | |
| } | |
| .section-level-2 { | |
| margin-left: 15px; | |
| padding-left: 10px; | |
| } | |
| .section-header-main { | |
| color: #1a237e; | |
| font-size: 20px; | |
| font-weight: 600; | |
| margin-bottom: 15px; | |
| padding-bottom: 5px; | |
| border-bottom: 1px solid #e8eaf6; | |
| } | |
| .section-header-sub { | |
| color: #283593; | |
| font-size: 16px; | |
| font-weight: 500; | |
| margin: 10px 0; | |
| } | |
| .section-content { | |
| color: #333; | |
| margin: 10px 0 10px 20px; | |
| line-height: 1.5; | |
| } | |
| .list-item { | |
| margin: 8px 0; | |
| color: #333; | |
| padding-left: 20px; | |
| position: relative; | |
| } | |
| .list-item:before { | |
| content: "•"; | |
| position: absolute; | |
| left: 0; | |
| color: #3949ab; | |
| } | |
| .nested-content { | |
| margin-left: 20px; | |
| padding-left: 15px; | |
| border-left: 2px solid #e8eaf6; | |
| } | |
| .timing-label { | |
| color: #1565c0; | |
| font-weight: 500; | |
| font-style: italic; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # Initialize generator | |
| #@st.cache_resource | |
| #def get_generator(): | |
| #return LessonPlanGenerator() | |
| generator = LessonPlanGenerator() | |
| # Header | |
| st.title("WizLab Lesson Plan Generator") | |
| st.markdown("We help you generate lesson plans tailored to your needs.") | |
| # Input section | |
| st.header("Input Your Requirements") | |
| # Create two columns for input fields | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| topic = st.text_input("Topic", placeholder="e.g., Lesson Plan to teach Spanish numbers as third language to English Speaking students ") | |
| age_group_options = ["Elementary (6-11)", "Middle School (12-14)", | |
| "High School (15-18)", "Adult Learners", "Other"] | |
| age_group_selection = st.selectbox("Target Age Group", age_group_options) | |
| if age_group_selection == "Other": | |
| age_group = st.text_input("Specify Age Group") | |
| else: | |
| age_group = age_group_selection | |
| language_options = [ | |
| "English", "日本語 (Japanese)", "中文 (Mandarin Chinese)", | |
| "Español (Spanish)", "हिंदी (Hindi)", "한국어 (Korean)", | |
| "Deutsch (German)", "Français (French)", "Português (Portuguese)", | |
| "العربية (Arabic)", "Русский (Russian)", "Other" | |
| ] | |
| language_selection = st.selectbox("Select Output Language", language_options) | |
| LANGUAGE_MAPPING = { | |
| "日本語 (Japanese)": "Japanese", | |
| "中文 (Mandarin Chinese)": "Mandarin Chinese", | |
| "Español (Spanish)": "Spanish", | |
| "हिंदी (Hindi)": "Hindi", | |
| "한국어 (Korean)": "Korean", | |
| "Deutsch (German)": "German", | |
| "Français (French)": "French", | |
| "Português (Portuguese)": "Portuguese", | |
| "العربية (Arabic)": "Arabic", | |
| "Русский (Russian)": "Russian" | |
| } | |
| # Then in your language selection code: | |
| if language_selection == "Other": | |
| language = st.text_input("Specify Language") | |
| else: | |
| # Use mapping if available, otherwise use the base language name | |
| language = LANGUAGE_MAPPING.get(language_selection, language_selection) | |
| #if language_selection == "Other": | |
| # language = st.text_input("Specify Language") | |
| # else: | |
| # Extract the base language name without the native script | |
| # language = language_selection.split(" (")[0] if " (" in language_selection else language_selection | |
| with col2: | |
| #duration_options = ["30 minutes", "45 minutes", "60 minutes", "90 minutes", "Other"] | |
| #duration_selection = st.selectbox("Lesson Duration", duration_options) | |
| #if duration_selection == "Other": | |
| # duration = st.text_input("Specify Duration") | |
| #else: | |
| # duration = duration_selection | |
| duration = st.text_input("Duration [in minutes]", placeholder = "e.g., 25 minutes") | |
| proficiency_options = ["Beginner [A1]", "Elementary [A2]", "Intermediate[B1, B2]", "Advanced[C1]", "Proficient [C2]", "Other"] | |
| proficiency_selection = st.selectbox("Proficiency Level [CEFR]", proficiency_options) | |
| if proficiency_selection == "Other": | |
| proficiency = st.text_input("Specify Proficiency Level") | |
| else: | |
| proficiency = proficiency_selection | |
| tech_options = ["Interactive Whiteboard", "Computers/Laptops", | |
| "Mobile Devices", "Internet Access", "None", "Other"] | |
| tech_selection = st.multiselect("Accessible Tech Resources", tech_options) | |
| if "Other" in tech_selection: | |
| other_tech = st.text_input("Specify Other Technology Requirements") | |
| tech_usage = [tech for tech in tech_selection if tech != "Other"] + [other_tech] | |
| else: | |
| tech_usage = tech_selection | |
| def format_content(data): | |
| html_content = '<div class="main-container">' | |
| def format_key(key): | |
| """Format key string to be more readable""" | |
| # Handle camelCase | |
| key = ''.join(' ' + char if char.isupper() else char for char in key).strip() | |
| # Replace underscores and normalize spaces | |
| key = key.replace('_', ' ').title() | |
| return key | |
| def process_value(value, level=0): | |
| if isinstance(value, dict): | |
| return process_dict(value, level) | |
| elif isinstance(value, list): | |
| return process_list(value, level) | |
| else: | |
| return f'<div class="section-content">{value}</div>' | |
| def process_dict(d, level): | |
| content = "" | |
| for key, value in d.items(): | |
| formatted_key = format_key(key) | |
| section_class = "section-level-" + str(level) | |
| content += f'<div class="section {section_class}">' | |
| if level == 0: | |
| content += f'<div class="section-header-main">{formatted_key}</div>' | |
| else: | |
| content += f'<div class="section-header-sub">{formatted_key}</div>' | |
| if isinstance(value, dict) and any(isinstance(v, (dict, list)) for v in value.values()): | |
| content += process_value(value, level + 1) | |
| elif isinstance(value, list) and any(isinstance(item, dict) for item in value): | |
| content += process_value(value, level + 1) | |
| else: | |
| content += process_value(value, level + 1) | |
| content += '</div>' | |
| return content | |
| def process_list(lst, level): | |
| content = '<div class="section-content">' | |
| for item in lst: | |
| if isinstance(item, dict): | |
| content += process_dict(item, level + 1) | |
| else: | |
| content += f'<div class="list-item">{item}</div>' | |
| content += '</div>' | |
| return content | |
| html_content += process_dict(data, 0) | |
| html_content += '</div>' | |
| return html_content | |
| # Generate button | |
| # Generate button | |
| if st.button("Generate Lesson Plan", type="primary"): | |
| if not topic: | |
| st.error("Please enter a topic for the lesson plan.") | |
| else: | |
| with st.spinner("Generating your lesson plan..."): | |
| # Set default values if not provided | |
| if not duration: | |
| duration = "30 minutes" | |
| if not proficiency: | |
| proficiency = "Intermediate [B1, B2]" | |
| if not age_group: | |
| age_group = "Elementary (6-11)" | |
| if not tech_usage: | |
| tech_usage = ["White Board", "Internet Access"] | |
| if not language: | |
| language = "English" | |
| detailed_prompt = f""" | |
| Create a lesson plan for teaching '{topic}' to {age_group} students. | |
| Duration: {duration} minutes, | |
| Proficiency Level [CEFR]: {proficiency}, | |
| Technology Requirements: {', '.join(tech_usage) if tech_usage else 'None'}, | |
| Generate response in {language} Language. | |
| """ | |
| try: | |
| # Pass both the prompt and language | |
| result = generator.generate_lesson_plan(detailed_prompt, language) | |
| # Consistent parsing regardless of language | |
| if isinstance(result, dict): | |
| if "lessonPlan" in result: | |
| lesson_content = result["lessonPlan"] | |
| else: | |
| lesson_content = result | |
| st.success("Lesson plan generated successfully!") | |
| # Create tabs for different views | |
| tab1, tab2 = st.tabs(["Formatted View", "Raw JSON"]) | |
| with tab1: | |
| st.markdown(format_content(lesson_content), unsafe_allow_html=True) | |
| with tab2: | |
| st.json(lesson_content) | |
| # Download button | |
| st.download_button( | |
| label="Download Lesson Plan", | |
| data=json.dumps(lesson_content, indent=2, ensure_ascii=False), | |
| # ensure_ascii=False for proper Unicode handling | |
| file_name=f"lesson_plan_{language}.json", | |
| mime="application/json" | |
| ) | |
| else: | |
| st.error("Invalid response format") | |
| except Exception as e: | |
| st.error(f"An error occurred: {str(e)}") | |
| # Footer | |
| st.markdown("---") | |