Spaces:
Runtime error
Runtime error
| # utils/learning_module.py | |
| from datetime import datetime | |
| import json | |
| from pathlib import Path | |
| import streamlit as st | |
| import base64 | |
| from PIL import Image | |
| import io | |
| TRADING_COURSES = { | |
| "Trading 101": { | |
| "title": "Introduction to Trading", | |
| "description": "Foundation course for beginners", | |
| "modules": [ | |
| { | |
| "title": "Understanding Markets", | |
| "topics": [ | |
| {"name": "What are Financial Markets", "requires_visuals": True}, | |
| {"name": "Types of Markets (Stocks, Forex, Crypto)", "requires_visuals": True}, | |
| {"name": "Market Participants", "requires_visuals": False}, | |
| {"name": "Basic Market Mechanics", "requires_visuals": True} | |
| ] | |
| }, | |
| { | |
| "title": "Trading Basics", | |
| "topics": [ | |
| {"name": "What is Trading", "requires_visuals": False}, | |
| {"name": "Different Trading Styles", "requires_visuals": False}, | |
| {"name": "Basic Chart Reading", "requires_visuals": True}, | |
| {"name": "Understanding Price Action", "requires_visuals": True} | |
| ] | |
| }, | |
| { | |
| "title": "Risk Management", | |
| "topics": [ | |
| {"name": "Importance of Risk Management", "requires_visuals": True}, | |
| {"name": "Position Sizing", "requires_visuals": True}, | |
| {"name": "Stop Loss Basics", "requires_visuals": True}, | |
| {"name": "Risk-Reward Ratio", "requires_visuals": True} | |
| ] | |
| } | |
| ] | |
| }, | |
| # Similar structure for Trading 201 and 301... | |
| } | |
| class LearningContent: | |
| def __init__(self, text_content, diagrams=None, examples=None): | |
| self.text_content = text_content | |
| self.diagrams = diagrams or [] | |
| self.examples = examples or [] | |
| class LearningModule: | |
| def __init__(self, claude_service): | |
| self.claude_service = claude_service | |
| self.data_dir = Path("data") | |
| self.learning_dir = self.data_dir / "learning" | |
| self.content_dir = self.learning_dir / "content" | |
| self.images_dir = self.learning_dir / "images" | |
| self.setup_directories() | |
| def setup_directories(self): | |
| """Create necessary directories""" | |
| for directory in [self.data_dir, self.learning_dir, self.content_dir, self.images_dir]: | |
| directory.mkdir(parents=True, exist_ok=True) | |
| def get_diagram_prompt(self, topic, concept): | |
| """Create a prompt for generating a diagram""" | |
| return f"""Create a clear, educational diagram to explain '{concept}' for {topic}. | |
| Make the diagram simple yet informative, suitable for learning purposes. | |
| Focus on key visual elements that help explain the concept. | |
| Use clear labels and annotations. | |
| Include a brief title and legend if necessary.""" | |
| def get_course_content(self, course_name, topic_data): | |
| """Get or generate detailed content for a specific topic""" | |
| topic = topic_data["name"] | |
| try: | |
| # Create unique identifier for content | |
| content_id = f"{course_name}_{topic}".replace(" ", "_").lower() | |
| content_file = self.content_dir / f"{content_id}.json" | |
| # Check if content is cached | |
| if content_file.exists(): | |
| with open(content_file, 'r') as f: | |
| stored_content = json.load(f) | |
| return LearningContent(**stored_content) | |
| # Generate new content | |
| base_prompt = f"""Create a comprehensive lesson for the topic '{topic}' in the {course_name} course. | |
| Structure the content as follows: | |
| 1. Overview | |
| 2. Key Concepts | |
| 3. Practical Examples | |
| 4. Common Mistakes to Avoid | |
| 5. Practice Exercises | |
| 6. Additional Resources | |
| Make this suitable for the course level: | |
| - Trading 101: Basic concepts, simple language | |
| - Trading 201: Intermediate concepts, some technical terms | |
| - Trading 301: Advanced concepts, technical language | |
| """ | |
| text_content = self.claude_service.generate_educational_content(base_prompt) | |
| diagrams = [] | |
| examples = [] | |
| # Generate diagrams if needed | |
| if topic_data.get("requires_visuals", False): | |
| # Extract key concepts for visualization | |
| concepts_prompt = f"List the 3 most important concepts from '{topic}' that would benefit from visual representation." | |
| concepts = self.claude_service.generate_educational_content(concepts_prompt).split('\n') | |
| for concept in concepts: | |
| # Generate diagram for each concept | |
| diagram_prompt = self.get_diagram_prompt(topic, concept) | |
| diagram = self.claude_service.generate_diagram(diagram_prompt) | |
| if diagram: | |
| # Save diagram | |
| diagram_filename = f"{content_id}_{len(diagrams)}.svg" | |
| diagram_path = self.images_dir / diagram_filename | |
| with open(diagram_path, 'w') as f: | |
| f.write(diagram) | |
| diagrams.append(diagram_filename) | |
| # Generate an example using the diagram | |
| example_prompt = f"Create a practical example explaining {concept} using the diagram." | |
| example = self.claude_service.generate_educational_content(example_prompt) | |
| examples.append({ | |
| 'concept': concept, | |
| 'example': example, | |
| 'diagram': diagram_filename | |
| }) | |
| # Create and cache content | |
| content = LearningContent( | |
| text_content=text_content, | |
| diagrams=diagrams, | |
| examples=examples | |
| ) | |
| with open(content_file, 'w') as f: | |
| json.dump(vars(content), f) | |
| return content | |
| except Exception as e: | |
| st.error(f"Error generating course content: {str(e)}") | |
| return None | |
| def display_content(self, content): | |
| """Display multi-modal content in the UI""" | |
| if not content: | |
| return | |
| # Display main content | |
| st.markdown(content.text_content) | |
| # Display examples with diagrams | |
| if content.examples: | |
| st.subheader("Interactive Examples") | |
| for example in content.examples: | |
| with st.expander(f"Example: {example['concept']}"): | |
| # Display diagram | |
| diagram_path = self.images_dir / example['diagram'] | |
| if diagram_path.exists(): | |
| with open(diagram_path, 'r') as f: | |
| svg_content = f.read() | |
| st.image(svg_content, use_container_width=True) | |
| # Display explanation | |
| st.markdown(example['example']) | |
| # Add interactive elements | |
| st.markdown("---") | |
| st.write("Try it yourself:") | |
| user_input = st.text_area("Practice your understanding:", key=f"practice_{example['concept']}") | |
| if st.button("Check Understanding", key=f"check_{example['concept']}"): | |
| feedback = self.claude_service.generate_educational_content( | |
| f"Provide constructive feedback on this understanding of {example['concept']}: {user_input}" | |
| ) | |
| st.write(feedback) | |
| def display_course_selection(self): | |
| """Display course selection interface""" | |
| st.subheader("Trading Courses") | |
| # Course selection | |
| selected_course = st.selectbox( | |
| "Select a Course", | |
| list(TRADING_COURSES.keys()), | |
| key="course_selector" | |
| ) | |
| course_data = TRADING_COURSES[selected_course] | |
| st.write(course_data["description"]) | |
| # Module selection | |
| selected_module = st.selectbox( | |
| "Select a Module", | |
| [module["title"] for module in course_data["modules"]], | |
| key="module_selector" | |
| ) | |
| # Find selected module data | |
| module_data = next(m for m in course_data["modules"] if m["title"] == selected_module) | |
| # Topic selection | |
| selected_topic_name = st.selectbox( | |
| "Select a Topic", | |
| [topic["name"] for topic in module_data["topics"]], | |
| key="topic_selector" | |
| ) | |
| selected_topic = next(t for t in module_data["topics"] if t["name"] == selected_topic_name) | |
| if st.button("Start Learning", key="start_learning"): | |
| with st.spinner("Loading content..."): | |
| content = self.get_course_content(selected_course, selected_topic) | |
| if content: | |
| self.display_content(content) | |
| def display_custom_learning(self): | |
| """Display custom learning interface""" | |
| st.subheader("Ask Any Trading Question") | |
| question = st.text_input( | |
| "What would you like to learn about?", | |
| key="custom_question" | |
| ) | |
| needs_visual = st.checkbox("Include visual explanation", value=True) | |
| if st.button("Get Answer", key="custom_answer"): | |
| if question: | |
| with st.spinner("Generating response..."): | |
| # Generate text response | |
| response = self.claude_service.generate_educational_content(question) | |
| if needs_visual: | |
| # Generate diagram | |
| diagram = self.claude_service.generate_diagram( | |
| self.get_diagram_prompt("Custom Learning", question) | |
| ) | |
| if diagram: | |
| # Save diagram | |
| diagram_filename = f"custom_{datetime.now().strftime('%Y%m%d_%H%M%S')}.svg" | |
| diagram_path = self.images_dir / diagram_filename | |
| with open(diagram_path, 'w') as f: | |
| f.write(diagram) | |
| # Display content | |
| st.markdown(response) | |
| with open(diagram_path, 'r') as f: | |
| svg_content = f.read() | |
| st.image(svg_content, use_container_width=True) | |
| else: | |
| st.markdown(response) |