Stock_Agent_optimized / utils /learning_module.py
cryogenic22's picture
Create utils/learning_module.py
37569f6 verified
# 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)