From 3df69c83cd5376bde0df03c8ff9d90723941b0e5 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 9 Nov 2025 14:36:10 +0000 Subject: [PATCH 1/7] Add comprehensive activity creation expert guide to CLAUDE.md This guide empowers agents to create activities that validate properly, are fun and engaging, and terminate correctly. Key additions: - Core activity structure with detailed examples - Critical validation requirements checklist - Four termination patterns with code examples - Ten engagement techniques from successful activities - Best practices for activity development - Common pitfalls table with fixes - Complete development workflow - Quick reference for essential fields - Minimal working activity example References activity26-magic-8-ball.yaml, activity31-scientific-method.yaml, and activity37-programming-languages.yaml as exemplary activities. --- CLAUDE.md | 617 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 617 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index 5e1bde3..2e313f3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -219,3 +219,620 @@ ollama run unsloth/qwen3-coder:30b-instruct-q4_K_M export MODEL_ENDPOINT_3=http://localhost:11434/v1 export MODEL_API_KEY_3=dummy ``` + +## Creating Activity YAML Files - Expert Guide + +When creating activities for OpenCompletion, follow these expert guidelines to ensure your activities **validate properly**, are **FUN and engaging**, and **terminate correctly**. + +### Core Activity Structure + +Every activity YAML file consists of: + +```yaml +# Optional: Global settings +default_max_attempts_per_step: 3 # Default retry limit +classifier_model: "MODEL_1" # Model for categorizing responses +feedback_model: "MODEL_1" # Model for generating feedback +tokens_for_ai_rubric: | # Global rubric for all steps + Evaluate the student's understanding... + +# Required: Sections contain steps +sections: + - section_id: "introduction" # Must be unique + title: "Welcome" # Descriptive title + steps: + - step_id: "welcome" # Must be unique within section + title: "Getting Started" + # Either content_blocks OR question (or both) + content_blocks: # Display-only content + - "Welcome message" + question: "Ready?" # Interactive question + buckets: [ready, not_ready] # Response categories + transitions: # One per bucket + ready: + next_section_and_step: "section_1:step_1" +``` + +**Two Types of Steps:** + +1. **Content-Only Steps** - Display information, automatically advance + ```yaml + - step_id: "info" + title: "Information" + content_blocks: + - "This is informational content." + - "It displays and auto-advances." + ``` + +2. **Question Steps** - Interactive, require user response + ```yaml + - step_id: "quiz" + title: "Question" + question: "What is 2+2?" + tokens_for_ai: | + Categorize as 'correct' if answer is 4 or 'four'. + Otherwise 'incorrect'. + buckets: [correct, incorrect] + transitions: + correct: + content_blocks: ["Great job!"] + next_section_and_step: "next_section:next_step" + incorrect: + content_blocks: ["Try again!"] + next_section_and_step: "quiz_section:quiz" + ``` + +### CRITICAL: Validation Requirements + +**MUST-PASS Checklist** (from activity_yaml_validator.py): + +#### Structure Requirements +- ✅ **Every activity must have `sections`** (at least one) +- ✅ **Every section needs**: `section_id`, `title`, `steps` +- ✅ **Every step needs**: `step_id`, `title`, and either `content_blocks` OR `question` +- ✅ **Section IDs must be unique** within the activity +- ✅ **Step IDs must be unique** within each section + +#### Bucket & Transition Requirements +- ✅ **Every bucket MUST have a corresponding transition** (CRITICAL!) + ```yaml + # WRONG - Missing transition for 'maybe' bucket + buckets: [yes, no, maybe] + transitions: + yes: {...} + no: {...} + # ❌ ERROR: No transition for 'maybe' + + # CORRECT - All buckets have transitions + buckets: [yes, no, maybe] + transitions: + yes: {...} + no: {...} + maybe: {...} # ✅ Every bucket covered + ``` + +#### Termination Requirements +- ✅ **Terminal steps (last step of last section with no next_section_and_step) CANNOT have questions** + ```yaml + # WRONG - Terminal step with question + - section_id: "conclusion" + steps: + - step_id: "final" + question: "How did you like it?" # ❌ ERROR + buckets: [good, bad] + transitions: + good: {} # No next_section_and_step = terminal + bad: {} + + # CORRECT - Terminal step with content only + - section_id: "conclusion" + steps: + - step_id: "final" + title: "Goodbye" + content_blocks: # ✅ Content only + - "Thank you for playing!" + ``` + +#### Transition Target Requirements +- ✅ **All `next_section_and_step` targets must exist** + ```yaml + # Format: "section_id:step_id" + next_section_and_step: "section_2:step_1" # Must exist! + ``` + +#### Python Code Requirements +- ✅ **All `processing_script` and `pre_script` must be syntactically valid Python** + ```yaml + # CORRECT + processing_script: | + result = user_input.lower() + metadata['guess'] = result + + # WRONG - Syntax error + processing_script: | + result = user_input.lower( # ❌ Missing closing paren + ``` + +#### Model Configuration (Optional) +- ✅ **`classifier_model` and `feedback_model` must be strings if specified** + ```yaml + classifier_model: "MODEL_1" # ✅ Correct + feedback_model: MODEL_1 # ❌ Wrong (unquoted) + ``` + +### How to Properly Terminate Activities + +Activities can terminate in four ways: + +#### 1. Content-Only Terminal Step (Simplest) +Last step of last section has only `content_blocks`, no question: +```yaml +sections: + - section_id: "conclusion" + steps: + - step_id: "goodbye" + title: "Farewell" + content_blocks: + - "Thank you for playing! 🎉" + - "Come back anytime!" + # No question = auto-terminates +``` + +#### 2. Final Reflection Question (Educational Activities) +Last step has question, but NO transitions specify `next_section_and_step`: +```yaml +sections: + - section_id: "conclusion" + steps: + - step_id: "reflection" + title: "Final Thoughts" + question: "What did you learn today?" + tokens_for_ai: "Provide encouraging feedback on their reflection." + buckets: [thoughtful, brief, off_topic] + transitions: + thoughtful: + ai_feedback: + tokens_for_ai: "Celebrate their learning!" + metadata_add: + activity_completed: "true" + # No next_section_and_step = terminates + brief: + ai_feedback: + tokens_for_ai: "Thank them for their time." + metadata_add: + activity_completed: "true" + off_topic: + content_blocks: + - "Please reflect on what you learned." + next_section_and_step: "conclusion:reflection" # Retry +``` + +#### 3. Explicit Exit Transition (Games/Interactive) +Create an 'exit' bucket that leads to a goodbye step: +```yaml +- step_id: "play_again" + question: "Would you like to play again?" + buckets: [yes, exit] + transitions: + yes: + metadata_clear: true # Reset game state + next_section_and_step: "game:start" + exit: + next_section_and_step: "conclusion:goodbye" # Jump to end +``` + +#### 4. Max Attempts Exhausted (Automatic Fallback) +After 3 failed attempts (default), system auto-advances: +```yaml +default_max_attempts_per_step: 3 + +# After 3 attempts, automatically moves to next step +# Use counts_as_attempt: false for transitions that shouldn't count +transitions: + correct: + next_section_and_step: "next:step" + hint: + content_blocks: ["Here's a hint..."] + counts_as_attempt: false # Doesn't count toward max + next_section_and_step: "current:step" # Retry + incorrect: + content_blocks: ["Try again!"] + next_section_and_step: "current:step" # Retry (counts) +``` + +**CRITICAL Termination Rule**: Use `metadata_add: activity_completed: "true"` in your final transitions to mark completion! + +### What Makes Activities FUN and Engaging + +Study activity26-magic-8-ball.yaml, activity31-scientific-method.yaml, and activity37-programming-languages.yaml for examples. + +#### 1. **Looping/Replayability** +Allow users to repeat fun parts: +```yaml +# Magic 8 Ball - loops back to itself +transitions: + ask_question: + ai_feedback: {...} + next_section_and_step: "section_1:step_1" # Loop! + exit: + next_section_and_step: "section_1:goodbye" +``` + +#### 2. **Randomness & Variety** +Use `metadata_tmp_random` or `metadata_random` for unpredictability: +```yaml +transitions: + roll_dice: + metadata_tmp_random: + dice_result: [1, 2, 3, 4, 5, 6] # Random pick + ai_feedback: + tokens_for_ai: | + The dice roll is in metadata.dice_result. + Announce it dramatically! 🎲 +``` + +#### 3. **Personalization with Metadata** +Store and reference user choices throughout: +```yaml +# Step 1: Store user's name +transitions: + greeting: + metadata_add: + player_name: "the-users-response" + +# Step 5: Reference their name +tokens_for_ai: | + Address the user by their name from metadata.player_name. + Make it personal! +``` + +#### 4. **AI Personality & Encouragement** +Make the AI engaging: +```yaml +ai_feedback: + tokens_for_ai: | + Be enthusiastic! Use emojis! 🎉 + Celebrate their success with a joke related to their answer. + On a new line, encourage them to continue. +``` + +#### 5. **Progressive Scoring** +Track and display progress: +```yaml +metadata_add: + score: "n+1" # Increment score + correct_answers: "n+1" + +# In final step +content_blocks: + - "Your final score: check metadata.score" + - "You got metadata.correct_answers correct!" +``` + +#### 6. **Multiple Valid Paths** +Different quality responses get different feedback: +```yaml +buckets: + - excellent_answer # Perfect understanding + - correct_answer # Got it right + - partial_understanding # On the right track + - creative_thinking # Wrong but interesting + - needs_help # Need more guidance + - off_topic # Completely off + +# Each bucket gets tailored feedback and appropriate next step +``` + +#### 7. **Visual Variety & Formatting** +Use markdown, emojis, and structure: +```yaml +content_blocks: + - "# Welcome to the Adventure! 🗺️" + - "You stand at a crossroads..." + - "" + - "**North**: A dark forest 🌲" + - "**South**: A sunny beach 🏖️" + - "**East**: A mysterious cave 🕳️" + - "" + - "Where will you go?" +``` + +#### 8. **Educational Scaffolding** +Build complexity gradually: +```yaml +# Section 1: Simple concepts with lots of support +# Section 2: Intermediate - less hand-holding +# Section 3: Advanced - challenging applications +# Section 4: Reflection and synthesis +``` + +#### 9. **Role-Playing & Storytelling** +Create engaging narratives: +```yaml +tokens_for_ai: | + You are a wise wizard guiding the student. + Stay in character! Speak mysteriously. + Reference their previous choices from metadata. +``` + +#### 10. **Immediate, Specific Feedback** +Don't just say "correct" or "wrong": +```yaml +feedback_tokens_for_ai: | + If they identified the scientific method correctly: + - Praise the specific insight they showed + - Connect it to real-world applications + - Encourage them to apply this thinking + + If they struggled: + - Acknowledge what they got right first + - Gently correct the misunderstanding + - Provide a hint or example + - Encourage them to try again +``` + +### Best Practices for Activity Creation + +1. **Start with the Learning Goals** + - What should the user know/be able to do after completion? + - Design backwards from those outcomes + +2. **Write Clear AI Instructions** + ```yaml + # VAGUE - AI won't know what to do + tokens_for_ai: "Check if they understand." + + # SPECIFIC - AI knows exactly what to do + tokens_for_ai: | + Categorize as 'correct' if they mention: + - Variables store data + - Types define what kind of data + - Examples: strings, numbers, booleans + + Categorize as 'partial' if they only mention one aspect. + Categorize as 'incorrect' otherwise. + ``` + +3. **Design Metadata Strategically** + - Store meaningful state that affects the experience + - Don't track everything - only what you'll reference + - Use descriptive key names: `programming_language` not `pl` + +4. **Test All Paths** + ```bash + # Use the CLI simulator + source vars.sh + python research/guarded_ai.py research/your_activity.yaml + + # Try: + # - Correct answers + # - Wrong answers + # - Edge cases + # - Max attempts exhaustion + # - Language switching + # - All branches/sections + ``` + +5. **Validate Early and Often** + ```bash + python activity_yaml_validator.py research/your_activity.yaml + ``` + +6. **Use Comments Liberally** + ```yaml + # This section teaches variables + # User's chosen language is in metadata.programming_language + - section_id: "variables" + steps: + # First, explain what variables are + - step_id: "explain" + # ... then quiz them + - step_id: "quiz" + ``` + +7. **Provide Multiple Difficulty Paths** + ```yaml + # Allow users to request hints + buckets: [correct, incorrect, need_hint] + transitions: + need_hint: + content_blocks: ["Hint: Think about..."] + counts_as_attempt: false + next_section_and_step: "current:question" # Retry + ``` + +8. **Support Language Switching** + Always include a `set_language` bucket: + ```yaml + buckets: [answer, set_language, off_topic] + transitions: + set_language: + content_blocks: + - "Language preference updated." + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: "current:step" # Retry in new language + ``` + +9. **Write Engaging Content Blocks** + ```yaml + # BORING + content_blocks: + - "This is about variables." + + # ENGAGING + content_blocks: + - "# Let's Talk About Variables! 📦" + - "Imagine your computer's memory as a huge warehouse..." + - "Variables are like labeled boxes where you store information." + - "" + - "**Why do we need them?** Without variables, programs can't remember anything!" + ``` + +10. **Design for Replayability** + - Use randomness for variety + - Support restart/retry paths + - Allow skipping to different sections + - Make it fun to play multiple times + +### Common Pitfalls to AVOID + +| Pitfall | Why It Fails Validation | How to Fix | +|---------|------------------------|------------| +| **Missing transition for a bucket** | Every bucket MUST have a transition | Add transition for ALL buckets | +| **Terminal step with question** | Last step of last section cannot have questions/buckets | Make final step content-only | +| **Circular loop without exit** | Users get trapped, max_attempts saves them but feels bad | Always provide an 'exit' bucket or progression path | +| **Invalid transition target** | References non-existent section:step | Verify all targets exist: `python activity_yaml_validator.py` | +| **Python syntax errors in scripts** | Crashes at runtime | Test your Python code before adding to YAML | +| **Vague AI instructions** | AI categorizes incorrectly, wrong buckets | Be specific about what makes each bucket | +| **Boolean values as strings** | `"true"` is a string, not boolean | Use `true/false` not `"true"/"false"` | +| **Forgetting `counts_as_attempt: false`** | Hints/language changes count as failures | Add `counts_as_attempt: false` to helper transitions | +| **No activity_completed marker** | Can't track completion | Add `metadata_add: activity_completed: "true"` to final transitions | +| **Inconsistent metadata keys** | `score` vs `Score` vs `total_score` | Pick one naming scheme and stick to it | +| **Too many attempts before feedback** | Users get frustrated | Default to 3 max, provide hints after attempt 1 | +| **Generic feedback** | "Good job!" isn't helpful | Reference specific parts of their answer | +| **Dead-end paths** | User stuck, can't progress | Always provide a way forward (even if it's restarting) | +| **Ignoring the rubric** | Global `tokens_for_ai_rubric` tells AI how to evaluate | Define it for consistency across steps | + +### Activity Development Workflow + +1. **Plan Structure** + - Sketch sections and learning progression + - Identify key decision points + - Map out metadata usage + +2. **Write YAML** + - Start with one section + - Test it in the simulator + - Expand incrementally + +3. **Validate** + ```bash + python activity_yaml_validator.py research/your_activity.yaml + ``` + +4. **Test Interactively** + ```bash + source vars.sh + python research/guarded_ai.py research/your_activity.yaml + ``` + +5. **Test All Paths** + - Try every bucket + - Exhaust max attempts + - Test edge cases + - Verify termination + +6. **Refine** + - Improve AI instructions based on testing + - Adjust bucket categories + - Polish content blocks + - Add variety and engagement + +7. **Final Validation** + - Run validator one more time + - Test complete playthrough + - Verify all transitions work + - Confirm proper termination + +### Quick Reference: Essential Fields + +```yaml +# Activity Level (Root) +default_max_attempts_per_step: 3 # Optional, defaults to 3 +classifier_model: "MODEL_1" # Optional, defaults to MODEL_1 +feedback_model: "MODEL_1" # Optional, defaults to MODEL_1 +tokens_for_ai_rubric: "..." # Optional global rubric +sections: [...] # REQUIRED + +# Section Level +section_id: "unique_id" # REQUIRED, unique +title: "Section Title" # REQUIRED +steps: [...] # REQUIRED + +# Step Level (Content-Only) +step_id: "unique_id" # REQUIRED, unique in section +title: "Step Title" # REQUIRED +content_blocks: [...] # REQUIRED (if no question) + +# Step Level (Question) +step_id: "unique_id" # REQUIRED +title: "Step Title" # REQUIRED +question: "Your question?" # REQUIRED (if no content_blocks) +tokens_for_ai: "Categorization rules" # Recommended +feedback_tokens_for_ai: "Feedback rules" # Recommended +buckets: [...] # REQUIRED (with question) +transitions: {...} # REQUIRED (with buckets) +classifier_model: "MODEL_1" # Optional step-level override +feedback_model: "MODEL_1" # Optional step-level override + +# Transition Level +next_section_and_step: "section:step" # Optional (omit to terminate) +content_blocks: [...] # Optional static feedback +ai_feedback: # Optional AI-generated feedback + tokens_for_ai: "..." # Prompt for feedback +metadata_add: {key: "value"} # Add/update metadata +metadata_tmp_add: {key: "value"} # Temporary metadata (one turn) +metadata_random: {key: [...]} # Add random value from list +metadata_tmp_random: {key: [...]} # Temporary random value +metadata_remove: "key" or ["key1", "key2"] # Remove metadata keys +metadata_clear: true # Clear all metadata +metadata_feedback_filter: ["key1", "key2"] # Filter feedback by metadata +counts_as_attempt: false # Don't count toward max_attempts +run_processing_script: true # Execute step's processing_script +``` + +### Example: Complete Minimal Activity + +```yaml +default_max_attempts_per_step: 3 +sections: + - section_id: "intro" + title: "Introduction" + steps: + - step_id: "welcome" + title: "Welcome" + content_blocks: + - "# Welcome to Math Quiz! 🔢" + - "Let's test your addition skills!" + + - step_id: "quiz" + title: "Addition Question" + question: "What is 5 + 7?" + tokens_for_ai: | + Categorize as 'correct' if they answer 12 or "twelve". + Categorize as 'close' if they're within 2 (10, 11, 13, 14). + Otherwise 'incorrect'. + buckets: [correct, close, incorrect] + transitions: + correct: + content_blocks: + - "Perfect! 🎉" + metadata_add: + score: "n+1" + next_section_and_step: "conclusion:goodbye" + close: + content_blocks: + - "Close! Think again." + next_section_and_step: "intro:quiz" + incorrect: + content_blocks: + - "Not quite. Try adding 5 + 7 again." + next_section_and_step: "intro:quiz" + + - section_id: "conclusion" + title: "Conclusion" + steps: + - step_id: "goodbye" + title: "Goodbye" + content_blocks: + - "Thanks for playing! 👋" +``` + +This activity: +- ✅ Validates (all required fields present) +- ✅ Is fun (emoji, encouraging feedback, score tracking) +- ✅ Terminates properly (content-only final step) + +**Now you're ready to create amazing activities!** 🚀 From 10d0ec27a2108b43e8ccf38aa059f7e4a0c26b70 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 9 Nov 2025 14:50:04 +0000 Subject: [PATCH 2/7] Add two fashion activities: modern style and historical journey activity38-fashion-today.yaml - Fun, interactive style discovery - Personal style identification (classic, boho, streetwear, etc.) - Color psychology and preferences - Outfit building for occasions - Statement pieces and accessories - Fashion philosophy reflection - Encourages self-expression and confidence activity39-fashion-history.yaml - Educational timeline 1800-2025 - Victorian era corsets and social restrictions - 1920s flappers and women's liberation - WWII rationing and practical fashion - 1950s ultra-femininity and gender politics - 1960s-70s revolution (mod, hippie, disco, punk) - 1980s excess and 1990s grunge backlash - 2000s-2010s fast fashion and social media - 2020s sustainability, inclusivity, technology - Critical thinking about fashion as social mirror Both activities: - Follow expert guide validation requirements - Include engaging content with emojis and formatting - Support language switching - Use metadata strategically - Have multiple response paths with tailored feedback - Terminate properly with activity_completed markers - Passed activity_yaml_validator.py with zero errors/warnings --- research/activity38-fashion-today.yaml | 591 +++++++++++ research/activity39-fashion-history.yaml | 1161 ++++++++++++++++++++++ 2 files changed, 1752 insertions(+) create mode 100644 research/activity38-fashion-today.yaml create mode 100644 research/activity39-fashion-history.yaml diff --git a/research/activity38-fashion-today.yaml b/research/activity38-fashion-today.yaml new file mode 100644 index 0000000..73d50c3 --- /dev/null +++ b/research/activity38-fashion-today.yaml @@ -0,0 +1,591 @@ +default_max_attempts_per_step: 3 +classifier_model: "MODEL_1" +feedback_model: "MODEL_1" +tokens_for_ai_rubric: | + Evaluate the student's engagement with fashion concepts. + + Consider: + - Their understanding of personal style + - Creativity in fashion choices + - Awareness of fashion principles (color, fit, occasion) + - Confidence in expressing their style + + Provide encouraging, personalized fashion advice. + Be supportive of all style preferences and body types. + +sections: + - section_id: introduction + title: Welcome to Fashion Today + steps: + - step_id: welcome + title: Fashion Journey Begins + content_blocks: + - "# Welcome to Fashion Today! 👗✨" + - "Fashion is more than clothes—it's self-expression, confidence, and creativity!" + - "" + - "**In this journey, you'll:**" + - "- Discover your personal style" + - "- Learn fashion principles" + - "- Build outfits for different occasions" + - "- Get personalized style advice" + - "" + - "**Remember:** Fashion has no rules, only guidelines. The best style is what makes YOU feel confident!" + question: Are you ready to explore the exciting world of fashion? + tokens_for_ai: | + Accept any positive response as 'ready'. + If setting language preference, categorize as 'set_language'. + Otherwise 'off_topic'. + buckets: + - ready + - set_language + - off_topic + transitions: + ready: + content_blocks: + - "Fantastic! Let's discover your unique style! 🌟" + next_section_and_step: style_discovery:step_1 + set_language: + content_blocks: + - "Language preference updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: introduction:welcome + off_topic: + content_blocks: + - "Let's focus on fashion! Are you excited to begin?" + counts_as_attempt: false + next_section_and_step: introduction:welcome + + - section_id: style_discovery + title: Discover Your Style + steps: + - step_id: step_1 + title: Fashion Inspiration + content_blocks: + - "## What's Your Style Vibe? 🎨" + - "" + - "**Popular fashion styles:**" + - "" + - "**Classic/Timeless** 🎩 - Elegant, tailored pieces; neutral colors; quality over trends" + - "**Casual/Comfortable** 👟 - Relaxed fits, denim, sneakers, effortless cool" + - "**Bohemian/Boho** 🌸 - Flowy fabrics, earthy tones, layered accessories, free-spirited" + - "**Streetwear/Urban** 🛹 - Bold graphics, sneakers, hoodies, influenced by music and skate culture" + - "**Romantic/Feminine** 🌹 - Soft colors, ruffles, lace, delicate details" + - "**Edgy/Alternative** 🖤 - Dark colors, leather, unconventional cuts, statement pieces" + - "**Minimalist** ⚪ - Clean lines, monochrome, simple silhouettes, 'less is more'" + - "**Preppy/Collegiate** 📚 - Polished, structured, blazers, button-downs, classic patterns" + - "**Glamorous/Luxe** ✨ - Sparkle, bold jewelry, luxurious fabrics, red carpet vibes" + - "**Eclectic/Mix-and-Match** 🎭 - Combining different styles, unique combinations, personal flair" + - "" + - "You can love multiple styles or create your own unique blend!" + question: Which style (or styles) resonates with you? Describe what you love about fashion or what you'd like to wear! + tokens_for_ai: | + The student is describing their fashion preferences. + + Store their response in metadata.style_preference. + + Categorize based on engagement level: + - detailed_response: They describe specific styles, colors, or preferences + - general_interest: They mention a style category or general interest + - exploring: They're unsure but curious + - set_language: Setting language preference + - off_topic: Unrelated to fashion + feedback_tokens_for_ai: | + Acknowledge their style preferences enthusiastically! + + If they mentioned specific styles: + - Validate their choices + - Mention how that style expresses personality + - Suggest complementary elements + + If they're exploring: + - Encourage experimentation + - Mention that style evolves + - Suggest trying different looks + buckets: + - detailed_response + - general_interest + - exploring + - set_language + - off_topic + transitions: + detailed_response: + ai_feedback: + tokens_for_ai: | + Celebrate their detailed style knowledge! + Reference specific elements they mentioned. + Tell them their style sounds amazing and expresses their personality. + metadata_add: + style_preference: "the-users-response" + score: "n+1" + next_section_and_step: style_discovery:step_2 + general_interest: + ai_feedback: + tokens_for_ai: | + Great starting point! + Acknowledge their style interest. + Encourage them to explore further. + metadata_add: + style_preference: "the-users-response" + next_section_and_step: style_discovery:step_2 + exploring: + content_blocks: + - "Exploring is wonderful! Fashion is about discovery." + - "Think about: What colors make you happy? What fabrics feel good? What makes you feel confident?" + metadata_add: + style_preference: "exploring different styles" + next_section_and_step: style_discovery:step_2 + set_language: + content_blocks: + - "Language updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: style_discovery:step_1 + off_topic: + content_blocks: + - "Let's talk fashion! What kind of clothes do you enjoy wearing?" + next_section_and_step: style_discovery:step_1 + + - step_id: step_2 + title: Color and You + content_blocks: + - "## The Power of Color 🌈" + - "" + - "Colors affect mood and perception!" + - "" + - "**Color Psychology:**" + - "- **Red** ❤️ - Bold, confident, passionate, attention-grabbing" + - "- **Blue** 💙 - Calm, trustworthy, professional, serene" + - "- **Black** 🖤 - Sophisticated, elegant, powerful, versatile" + - "- **White** 🤍 - Clean, fresh, minimalist, peaceful" + - "- **Yellow** 💛 - Happy, energetic, optimistic, cheerful" + - "- **Green** 💚 - Natural, balanced, refreshing, growth" + - "- **Pink** 💗 - Playful, romantic, soft, youthful" + - "- **Purple** 💜 - Creative, luxurious, mysterious, royal" + - "- **Neutrals** (beige, gray, brown) - Versatile, timeless, easy to mix" + - "" + - "**Pro Tip:** Wear colors near your face that complement your skin tone!" + question: What colors do you love to wear? What colors make you feel most confident or happy? + tokens_for_ai: | + Student is sharing color preferences. + + Categorize as: + - specific_colors: Names specific colors and why they like them + - color_mentioned: Mentions colors without detail + - neutral_preference: Prefers neutrals or all colors + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + Validate their color choices! + + Reference color psychology for their chosen colors. + Suggest how to incorporate those colors. + Mention complementary colors if appropriate. + buckets: + - specific_colors + - color_mentioned + - neutral_preference + - set_language + - off_topic + transitions: + specific_colors: + ai_feedback: + tokens_for_ai: | + Excellent color awareness! + Reference the psychology/meaning of their chosen colors. + Suggest outfit combinations or accent pieces. + Celebrate their color confidence! + metadata_add: + color_preference: "the-users-response" + score: "n+1" + next_section_and_step: outfit_building:step_1 + color_mentioned: + ai_feedback: + tokens_for_ai: | + Great choices! + Explain what those colors convey. + Encourage experimenting with different shades. + metadata_add: + color_preference: "the-users-response" + next_section_and_step: outfit_building:step_1 + neutral_preference: + ai_feedback: + tokens_for_ai: | + Neutrals are timeless and versatile! + Perfect base for any wardrobe. + Suggest adding pops of color through accessories. + metadata_add: + color_preference: "neutrals and versatile colors" + next_section_and_step: outfit_building:step_1 + set_language: + content_blocks: + - "Language updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: style_discovery:step_2 + off_topic: + content_blocks: + - "Think about your wardrobe! What colors do you reach for most often?" + next_section_and_step: style_discovery:step_2 + + - section_id: outfit_building + title: Build Your Wardrobe + steps: + - step_id: step_1 + title: Dressing for Occasions + content_blocks: + - "## Fashion for Every Occasion 👔👗" + - "" + - "**The Fashion Formula:** Occasion + Personal Style = Perfect Outfit" + - "" + - "**Key Principles:**" + - "" + - "1. **Dress Code Awareness**" + - " - Casual: Comfort meets style (jeans, sneakers, t-shirts)" + - " - Business Casual: Polished but approachable (slacks, blouses, loafers)" + - " - Formal: Sophisticated elegance (suits, dresses, dress shoes)" + - "" + - "2. **Fit is Everything**" + - " - Clothes should fit your body, not the other way around" + - " - Tailoring can transform any piece" + - " - Comfort = Confidence" + - "" + - "3. **The Power of Accessories**" + - " - Jewelry, bags, shoes, scarves" + - " - Can transform a basic outfit" + - " - Express personality" + - "" + - "**Let's practice outfit building!**" + question: "Imagine you're going to a casual coffee date with friends. What would you wear? Describe your outfit!" + tokens_for_ai: | + Student is describing a casual outfit. + + Look for: + - Specific clothing items + - Color coordination + - Style consistency + - Occasion appropriateness + + Categorize as: + - detailed_outfit: Describes multiple pieces with thought to coordination + - basic_outfit: Mentions clothing items appropriately casual + - creative_outfit: Unique or interesting combinations + - needs_guidance: Very brief or doesn't match occasion + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + Evaluate their outfit for the casual coffee date scenario. + + If well thought out: + - Praise specific choices + - Mention what works well + - Suggest one accessory or detail to elevate it + + If creative: + - Celebrate their unique style + - Encourage personal expression + + If needs work: + - Gently guide toward casual appropriate pieces + - Give specific suggestions + - Be encouraging + buckets: + - detailed_outfit + - basic_outfit + - creative_outfit + - needs_guidance + - set_language + - off_topic + transitions: + detailed_outfit: + ai_feedback: + tokens_for_ai: | + Excellent outfit planning! + Reference their style preference from metadata if stored. + Praise specific elements (color choices, coordination, etc.). + Suggest one perfect accessory to complete the look. + metadata_add: + score: "n+1" + outfits_created: "n+1" + next_section_and_step: outfit_building:step_2 + basic_outfit: + ai_feedback: + tokens_for_ai: | + Perfect for a casual coffee date! + Reference what they chose. + Suggest how to add personal flair (accessories, colors, etc.). + metadata_add: + outfits_created: "n+1" + next_section_and_step: outfit_building:step_2 + creative_outfit: + ai_feedback: + tokens_for_ai: | + Love the creativity! + Celebrate their unique fashion sense. + Encourage them to own their style. + metadata_add: + score: "n+1" + outfits_created: "n+1" + next_section_and_step: outfit_building:step_2 + needs_guidance: + content_blocks: + - "Let's think casual and comfortable!" + - "**Suggestions:** Jeans or casual pants, a nice top or sweater, comfortable shoes (sneakers, boots, flats)" + - "Add your personal touch with accessories or colors you love!" + next_section_and_step: outfit_building:step_1 + set_language: + content_blocks: + - "Language updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: outfit_building:step_1 + off_topic: + content_blocks: + - "Imagine your perfect casual outfit! What would you choose to wear for coffee with friends?" + next_section_and_step: outfit_building:step_1 + + - step_id: step_2 + title: Statement Pieces + content_blocks: + - "## The Power of Statement Pieces 💎" + - "" + - "**What's a Statement Piece?**" + - "An item that stands out and defines your outfit!" + - "" + - "**Examples:**" + - "- Bold jacket (leather, colorful blazer, denim)" + - "- Eye-catching shoes (colored sneakers, boots, heels)" + - "- Unique bag (vintage, designer, handmade)" + - "- Dramatic jewelry (chunky necklace, statement earrings)" + - "- Printed/patterned piece (floral dress, graphic tee, plaid pants)" + - "" + - "**The Rule:** Let your statement piece shine!" + - "- Keep other items simpler" + - "- Build outfit around the statement piece" + - "- One or two statement pieces max" + question: What's your favorite statement piece you own (or would love to own)? Describe it and how you'd style it! + tokens_for_ai: | + Student describing a statement piece. + + Categorize as: + - detailed_vision: Describes the piece AND how they'd wear it + - piece_described: Describes a statement item + - aspirational: Talks about wanting certain pieces + - minimalist_approach: Prefers subtle/no statement pieces + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + Respond to their statement piece choice! + + If they described styling: + - Praise their fashion vision + - Suggest complementary pieces + - Encourage them to rock it + + If minimalist: + - Validate that style too + - Mention statement can be subtle + - Quality basics are statements too + buckets: + - detailed_vision + - piece_described + - aspirational + - minimalist_approach + - set_language + - off_topic + transitions: + detailed_vision: + ai_feedback: + tokens_for_ai: | + Wow, you have a great fashion eye! + Love how you described both the piece and the styling. + Reference specific elements they mentioned. + Encourage them to wear it with confidence! + metadata_add: + score: "n+1" + next_section_and_step: fashion_wisdom:step_1 + piece_described: + ai_feedback: + tokens_for_ai: | + Great statement piece choice! + Suggest how to style it. + Mention what type of outfit it would elevate. + next_section_and_step: fashion_wisdom:step_1 + aspirational: + ai_feedback: + tokens_for_ai: | + Great fashion goals! + Encourage saving/hunting for that perfect piece. + Mention alternatives or similar items to explore. + Fashion dreams are fun! + next_section_and_step: fashion_wisdom:step_1 + minimalist_approach: + ai_feedback: + tokens_for_ai: | + Minimalism is a powerful statement! + Quality over quantity is wise. + Mention how simple pieces can be impactful. + next_section_and_step: fashion_wisdom:step_1 + set_language: + content_blocks: + - "Language updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: outfit_building:step_2 + off_topic: + content_blocks: + - "Think about your wardrobe! Do you have a favorite bold piece that makes an outfit special?" + next_section_and_step: outfit_building:step_2 + + - section_id: fashion_wisdom + title: Fashion Tips & Confidence + steps: + - step_id: step_1 + title: Your Fashion Philosophy + content_blocks: + - "## Fashion Wisdom 🌟" + - "" + - "**Universal Fashion Truths:**" + - "" + - "1. **Confidence is Your Best Accessory**" + - " - Wear what makes YOU feel amazing" + - " - Own your choices" + - "" + - "2. **Fashion Has No Size**" + - " - Every body is a fashion body" + - " - Dress for YOUR shape and comfort" + - "" + - "3. **Break the Rules**" + - " - Fashion 'rules' are just suggestions" + - " - Mix patterns, clash colors, be YOU" + - "" + - "4. **Sustainable Choices Matter**" + - " - Quality over quantity" + - " - Thrift, swap, upcycle" + - " - Fashion can be ethical" + - "" + - "5. **Express Yourself**" + - " - Your clothes tell your story" + - " - Change your style as you grow" + - " - Have fun with it!" + question: What does fashion mean to you? How do you want to express yourself through clothing? + tokens_for_ai: | + This is a reflection question about their fashion philosophy. + + Categorize as: + - thoughtful_reflection: Shares personal connection to fashion + - self_expression: Talks about expressing personality/identity + - practical_view: Focuses on function, comfort, practicality + - creative_view: Sees fashion as art/creativity + - brief_response: Short but genuine + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + Provide personalized, encouraging feedback! + + Reference their style_preference from metadata if available. + Celebrate their unique perspective on fashion. + Encourage them to continue expressing themselves. + Mention that fashion is a journey, not a destination. + buckets: + - thoughtful_reflection + - self_expression + - practical_view + - creative_view + - brief_response + - set_language + - off_topic + transitions: + thoughtful_reflection: + ai_feedback: + tokens_for_ai: | + Beautiful reflection on fashion! + Acknowledge their personal connection. + Reference their journey through this activity. + Encourage continued self-expression. + metadata_add: + score: "n+1" + activity_completed: "true" + next_section_and_step: conclusion:step_1 + self_expression: + ai_feedback: + tokens_for_ai: | + Fashion is the perfect medium for self-expression! + Celebrate their desire to show their personality. + Encourage authenticity in their style choices. + metadata_add: + activity_completed: "true" + next_section_and_step: conclusion:step_1 + practical_view: + ai_feedback: + tokens_for_ai: | + Practical fashion is smart fashion! + Function and style can coexist beautifully. + Acknowledge the value of comfort and versatility. + metadata_add: + activity_completed: "true" + next_section_and_step: conclusion:step_1 + creative_view: + ai_feedback: + tokens_for_ai: | + Fashion IS art! + Celebrate their creative perspective. + Encourage experimenting and pushing boundaries. + metadata_add: + activity_completed: "true" + next_section_and_step: conclusion:step_1 + brief_response: + ai_feedback: + tokens_for_ai: | + Thank them for sharing! + Summarize key fashion principles from this activity. + Encourage them to keep exploring their style. + metadata_add: + activity_completed: "true" + next_section_and_step: conclusion:step_1 + set_language: + content_blocks: + - "Language updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: fashion_wisdom:step_1 + off_topic: + content_blocks: + - "Let's reflect on fashion! What role do clothes play in your life and how you present yourself?" + next_section_and_step: fashion_wisdom:step_1 + + - section_id: conclusion + title: Your Fashion Journey Continues + steps: + - step_id: step_1 + title: Keep Shining + content_blocks: + - "## You're a Fashion Star! ⭐✨" + - "" + - "**What You've Explored:**" + - "✓ Discovered your personal style" + - "✓ Learned about colors and their power" + - "✓ Built outfits for different occasions" + - "✓ Explored statement pieces" + - "✓ Defined your fashion philosophy" + - "" + - "**Remember:**" + - "- Fashion is about feeling good in your skin" + - "- Confidence is the key to any outfit" + - "- Your style will evolve—embrace it!" + - "- There are no mistakes in fashion, only experiments" + - "" + - "**Next Steps:**" + - "- Clean out your closet (donate what doesn't serve you)" + - "- Try one new style element this week" + - "- Mix pieces you've never combined before" + - "- Take photos of outfits you love" + - "- Follow fashion inspiration that resonates with YOU" + - "" + - "**Your style is uniquely YOURS. Wear it proudly! 💖**" diff --git a/research/activity39-fashion-history.yaml b/research/activity39-fashion-history.yaml new file mode 100644 index 0000000..3f0e717 --- /dev/null +++ b/research/activity39-fashion-history.yaml @@ -0,0 +1,1161 @@ +default_max_attempts_per_step: 3 +classifier_model: "MODEL_1" +feedback_model: "MODEL_1" +tokens_for_ai_rubric: | + Evaluate the student's understanding of fashion history. + + Consider: + - Recognition of fashion trends across decades + - Understanding of historical context influencing fashion + - Ability to identify iconic fashion moments + - Appreciation for how fashion evolves with society + + Provide engaging, informative feedback with historical context. + +sections: + - section_id: introduction + title: Welcome to Fashion Through Time + steps: + - step_id: welcome + title: Time Travel Through Fashion + content_blocks: + - "# Fashion History: 1800-2025 🕰️👗" + - "" + - "**Welcome to a journey through 225 years of fashion!**" + - "" + - "Fashion isn't just about clothes—it's a mirror of society, politics, technology, and culture." + - "" + - "**You'll explore:**" + - "- How fashion reflected social changes" + - "- Iconic styles from each era" + - "- Revolutionary fashion moments" + - "- The evolution from corsets to comfort" + - "- How we got to today's diverse fashion landscape" + - "" + - "**Get ready to travel through time!** ⏰✨" + question: Are you ready to explore fashion history from the 1800s to today? + tokens_for_ai: | + Accept any positive response as 'ready'. + Language preference as 'set_language'. + Otherwise 'off_topic'. + buckets: + - ready + - set_language + - off_topic + transitions: + ready: + content_blocks: + - "Excellent! Let's begin in the 1800s... ⏰" + next_section_and_step: era_1800s:step_1 + set_language: + content_blocks: + - "Language preference updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: introduction:welcome + off_topic: + content_blocks: + - "Let's explore fashion history together! Ready to begin?" + counts_as_attempt: false + next_section_and_step: introduction:welcome + + - section_id: era_1800s + title: "1800s-1900: The Victorian Era" + steps: + - step_id: step_1 + title: Victorian Fashion + content_blocks: + - "## The 1800s: Victorian Elegance & Restriction 👑" + - "" + - "**The Era of Corsets and Crinolines**" + - "" + - "**Women's Fashion:**" + - "- **Tight corsets** creating the coveted hourglass figure" + - "- **Crinolines and bustles** making skirts impossibly wide" + - "- **High collars, long sleeves** - modesty was paramount" + - "- **Layers upon layers** - up to 20 pounds of clothing!" + - "- **Pale skin** was desirable (sign of wealth - no outdoor labor)" + - "" + - "**Men's Fashion:**" + - "- **Tailcoats and top hats** for formal occasions" + - "- **Three-piece suits** became the standard" + - "- **Waistcoats (vests)** in rich fabrics" + - "- **Strict dress codes** by time of day and occasion" + - "" + - "**Historical Context:**" + - "- Industrial Revolution changing fabric production" + - "- Strict social hierarchies reflected in dress" + - "- Women's restricted movement mirrored restricted rights" + - "- Fashion was about status and propriety" + - "" + - "**Late 1800s Change:**" + - "By the 1890s, the 'Gibson Girl' emerged—more active, athletic ideal" + question: What do you think Victorian fashion reveals about society at that time? Consider the tight corsets, heavy layers, and strict dress codes. + tokens_for_ai: | + Student analyzing Victorian fashion's social meaning. + + Look for understanding of: + - Gender roles and restrictions + - Social class divisions + - Values of modesty/propriety + - Women's limited freedom + + Categorize as: + - insightful_analysis: Connects fashion to social restrictions, gender roles, or class + - basic_observation: Notes the restrictive or formal nature + - curious_question: Asks questions or expresses interest + - brief_response: Short but relevant + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + Provide historical context to their observation! + + If they note restrictions: + - Affirm connection to women's limited rights + - Mention fashion as social control + - Note the health impacts of corsets + + Add interesting facts about the era. + Transition to the coming changes in the 1920s. + buckets: + - insightful_analysis + - basic_observation + - curious_question + - brief_response + - set_language + - off_topic + transitions: + insightful_analysis: + ai_feedback: + tokens_for_ai: | + Excellent historical analysis! + Affirm their insight about fashion reflecting social values. + Add: Corsets caused health problems, women couldn't even breathe deeply. + Fashion was literally restricting women's bodies and lives. + But change was coming... + metadata_add: + score: "n+1" + next_section_and_step: era_1920s:step_1 + basic_observation: + ai_feedback: + tokens_for_ai: | + Good observation! + Expand on it: The clothing reflected rigid social rules. + Women had few rights and fashion physically restricted them. + Mention this would dramatically change in coming decades. + next_section_and_step: era_1920s:step_1 + curious_question: + ai_feedback: + tokens_for_ai: | + Great curiosity! + Answer their question if they asked one. + Provide context about social restrictions and women's roles. + Tease upcoming dramatic fashion changes. + next_section_and_step: era_1920s:step_1 + brief_response: + ai_feedback: + tokens_for_ai: | + Yes! The Victorian era was about strict social control. + Fashion would soon undergo a revolution... + next_section_and_step: era_1920s:step_1 + set_language: + content_blocks: + - "Language updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: era_1800s:step_1 + off_topic: + content_blocks: + - "Think about what the restrictive clothing tells us about how society viewed women and social class in the 1800s." + next_section_and_step: era_1800s:step_1 + + - section_id: era_1920s + title: "1920s: The Roaring Twenties" + steps: + - step_id: step_1 + title: Flappers and Freedom + content_blocks: + - "## The 1920s: Revolution! ✨💃" + - "" + - "**The Flapper Era - Fashion Liberation**" + - "" + - "**What Changed:**" + - "- **Hemlines rose** from ankles to KNEES (scandalous!)" + - "- **Corsets disappeared** - loose, dropped-waist dresses" + - "- **Bobbed hair** - women cut their long hair short" + - "- **Makeup became acceptable** - dark lips, dramatic eyes" + - "- **Flat chests were 'in'** - goodbye hourglass, hello boyish figure" + - "" + - "**The Flapper Look:**" + - "- Beaded, fringed dresses that moved when dancing" + - "- Cloche hats worn low on the forehead" + - "- Long pearl necklaces" + - "- T-strap heels for dancing the Charleston" + - "- Fur stoles and cigarette holders" + - "" + - "**Why It Happened:**" + - "- WWI changed women's roles (they worked in factories)" + - "- Women gained the right to vote (1920 in US)" + - "- Jazz culture and speakeasies (Prohibition)" + - "- Young women rebelling against Victorian values" + - "- New freedom, new fashion!" + - "" + - "**Men's Fashion:**" + - "- Wide-legged Oxford bags (pants)" + - "- Raccoon fur coats" + - "- Two-tone spectator shoes" + - "- The 'Great Gatsby' look" + question: The 1920s saw dramatic fashion changes in just a few years. Why do you think fashion changed so radically after WWI? + tokens_for_ai: | + Student analyzing why 1920s fashion changed so dramatically. + + Look for mentions of: + - Women's changed roles/rights + - Post-war social change + - Rebellion against old values + - New freedoms and attitudes + - Technology/modernity + + Categorize as: + - connects_to_rights: Mentions women's suffrage, changing roles, or liberation + - social_change: Notes post-war society changes or rebellion + - freedom_theme: Talks about wanting freedom or rejecting restrictions + - basic_answer: Notes it changed but limited analysis + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + Validate their historical thinking! + + Key points to include: + - Women worked during war, gained independence + - Hard to go back to corsets after freedom + - Voting rights changed everything + - Young generation rejected parents' restrictive values + - Fashion reflected newfound freedom + + Add excitement about this revolutionary era! + buckets: + - connects_to_rights + - social_change + - freedom_theme + - basic_answer + - set_language + - off_topic + transitions: + connects_to_rights: + ai_feedback: + tokens_for_ai: | + Brilliant connection! + Yes - once women had the vote and independence, fashion HAD to change. + Can't fight for equality in a corset! + The flapper was a symbol of the "New Woman." + Fashion and freedom went hand in hand. + metadata_add: + score: "n+1" + next_section_and_step: era_1940s:step_1 + social_change: + ai_feedback: + tokens_for_ai: | + Exactly right! + Post-war, everything changed - women had tasted freedom. + The younger generation rejected Victorian restrictions. + Jazz, voting rights, and short skirts all represented liberation! + metadata_add: + score: "n+1" + next_section_and_step: era_1940s:step_1 + freedom_theme: + ai_feedback: + tokens_for_ai: | + Absolutely - it was all about freedom! + Women wanted to move, dance, work, vote, LIVE freely. + Fashion reflected that dramatic shift. + The 1920s flapper was a revolution in fabric form! + next_section_and_step: era_1940s:step_1 + basic_answer: + ai_feedback: + tokens_for_ai: | + Good thinking! + The key was women's changing roles after WWI. + They worked, gained the vote, and refused to go back to restrictions. + Fashion became a form of rebellion and freedom! + next_section_and_step: era_1940s:step_1 + set_language: + content_blocks: + - "Language updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: era_1920s:step_1 + off_topic: + content_blocks: + - "Think about how World War I changed women's roles in society. How might that affect what they wanted to wear?" + next_section_and_step: era_1920s:step_1 + + - section_id: era_1940s + title: "1940s: War & Rationing" + steps: + - step_id: step_1 + title: Fashion During WWII + content_blocks: + - "## The 1940s: Utility Fashion & Rosie the Riveter 💪" + - "" + - "**Fashion During World War II**" + - "" + - "**Fabric Rationing:**" + - "- Fabric, metal, leather all needed for war effort" + - "- Shorter hemlines (to save fabric)" + - "- No cuffs on pants, no extra pockets" + - "- Simple, practical designs" + - "- Women drew 'stocking seams' on bare legs (nylon was rationed!)" + - "" + - "**Women's Wartime Fashion:**" + - "- **Broad shoulders, nipped waist** - military influence" + - "- **A-line skirts** to conserve fabric" + - "- **Practical separates** - could mix and match" + - "- **Turbans and headscarves** (factory workers needed hair tied back)" + - "- **Overalls and trousers** became acceptable for women (work in factories)" + - "" + - "**'Rosie the Riveter' Style:**" + - "- Denim work clothes" + - "- Red bandana/headscarf" + - "- Practical, strong, capable" + - "- Fashion met function" + - "" + - "**Post-War (Late 1940s):**" + - "- 1947: Christian Dior's 'New Look' - celebration!" + - "- Full skirts, tiny waists, abundance of fabric" + - "- Return to ultra-femininity after wartime practicality" + question: How did WWII change what was considered acceptable for women to wear? Think about practical necessities versus fashion ideals. + tokens_for_ai: | + Analyzing how war changed women's fashion norms. + + Look for understanding of: + - Practicality over decoration + - Women wearing pants/work clothes + - Breaking gender norms out of necessity + - Resourcefulness during rationing + + Categorize as: + - practical_insight: Notes shift to practical, functional clothing + - gender_norms: Recognizes breaking of traditional women's dress codes + - resourceful_theme: Mentions rationing, making do, creativity + - good_observation: Relevant but general + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + Affirm their understanding! + + Key points: + - Women in factories needed practical clothes - pants became acceptable + - Rationing meant simple, versatile pieces + - Fashion took a back seat to winning the war + - But this permanently changed what women could wear + - Paved the way for women's pants becoming mainstream + + Note the irony of the post-war "New Look" trying to put women back in ultra-feminine clothes. + buckets: + - practical_insight + - gender_norms + - resourceful_theme + - good_observation + - set_language + - off_topic + transitions: + practical_insight: + ai_feedback: + tokens_for_ai: | + Excellent insight! + Yes - function over fashion was the rule. + Women working in factories couldn't wear frilly dresses! + This practical shift lasted beyond the war. + Once women wore pants, there was no going back! + metadata_add: + score: "n+1" + next_section_and_step: era_1950s:step_1 + gender_norms: + ai_feedback: + tokens_for_ai: | + Perfect observation! + The war shattered the idea that women couldn't wear pants or work clothes. + Necessity broke gender dress codes. + While the 1950s tried to push femininity again, the barrier was broken. + metadata_add: + score: "n+1" + next_section_and_step: era_1950s:step_1 + resourceful_theme: + ai_feedback: + tokens_for_ai: | + Great point about rationing! + Women got creative - drawing stocking seams, repurposing fabric, making do. + Simple, versatile pieces became the norm. + Less was more out of necessity! + next_section_and_step: era_1950s:step_1 + good_observation: + ai_feedback: + tokens_for_ai: | + Good thinking! + The war made practical work clothes acceptable for women. + This was a major shift - women in pants, working, active! + Fashion adapted to women's new roles. + next_section_and_step: era_1950s:step_1 + set_language: + content_blocks: + - "Language updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: era_1940s:step_1 + off_topic: + content_blocks: + - "Consider: Women worked in factories during the war. How did that change what they could wear compared to before?" + next_section_and_step: era_1940s:step_1 + + - section_id: era_1950s + title: "1950s: Post-War Glamour" + steps: + - step_id: step_1 + title: The New Look Era + content_blocks: + - "## The 1950s: Full Skirts & Hollywood Glamour 💃✨" + - "" + - "**The Return to Ultra-Femininity**" + - "" + - "**Dior's 'New Look' Dominates:**" + - "- **Full circle skirts** with layers of petticoats" + - "- **Tiny cinched waists** (belts and girdles)" + - "- **Soft shoulders** replacing the military look" + - "- **Mid-calf 'New Look' length**" + - "- Abundance of fabric = post-war optimism" + - "" + - "**Iconic 1950s Looks:**" + - "- **Poodle skirts** for teenagers" + - "- **Pencil skirts** for the office" + - "- **Sweater sets with pearls** - the suburban ideal" + - "- **Cat-eye glasses** and red lips" + - "- **Saddle shoes** and kitten heels" + - "" + - "**Youth Culture Emerges:**" + - "- Teenagers became a distinct group with their own fashion!" + - "- Rock 'n' roll influence (Elvis, leather jackets)" + - "- Rebels: James Dean's jeans and white t-shirt" + - "" + - "**The Ideal:**" + - "- Perfect housewife in pearls and heels (TV image)" + - "- Polished, proper, put-together" + - "- But... rebellion was brewing underneath" + question: The 1950s pushed ultra-feminine fashion after women worked in factories during WWII. Why do you think society wanted women to dress this way again? + tokens_for_ai: | + Critical thinking about post-war gender politics through fashion. + + Look for understanding of: + - Returning to traditional gender roles + - Taking jobs back for returning soldiers + - Social pressure/idealization of domesticity + - Push-back against women's independence + + Categorize as: + - critical_analysis: Recognizes social/political push to return women to traditional roles + - gender_politics: Notes attempt to make women more 'feminine' again + - cultural_observation: Comments on societal ideals or expectations + - basic_response: Notes the change without deep analysis + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + Validate their critical thinking! + + Historical context: + - Men returning from war needed jobs - women pushed out of factories + - Society wanted to return to 'normal' (pre-war gender roles) + - The perfect housewife was heavily promoted + - Fashion was used to reinforce traditional femininity + - But the 1960s would explode this ideal... + + Praise their analysis if sophisticated. + buckets: + - critical_analysis + - gender_politics + - cultural_observation + - basic_response + - set_language + - off_topic + transitions: + critical_analysis: + ai_feedback: + tokens_for_ai: | + Brilliant critical thinking! + Exactly - society wanted women back in traditional roles after the war. + Returning soldiers needed jobs, so women were pushed back to domesticity. + Ultra-feminine fashion was part of that push. + The "perfect housewife" image was propaganda! + But women had tasted freedom... the 1960s would change everything! + metadata_add: + score: "n+1" + next_section_and_step: era_1960s_70s:step_1 + gender_politics: + ai_feedback: + tokens_for_ai: | + Yes! This was absolutely about gender politics. + Society tried to make women more 'feminine' = more domestic. + Full skirts and pearls while vacuuming was the ideal. + Fashion reflected the pressure to conform. + The rebellion was coming... + metadata_add: + score: "n+1" + next_section_and_step: era_1960s_70s:step_1 + cultural_observation: + ai_feedback: + tokens_for_ai: | + Good observation! + The 1950s idealized the perfect housewife and mother. + Fashion was part of creating that image. + But not everyone bought into it - change was brewing! + next_section_and_step: era_1960s_70s:step_1 + basic_response: + ai_feedback: + tokens_for_ai: | + True! + After the war, society pushed traditional gender roles again. + Fashion was used to make women look ultra-feminine and domestic. + But the 1960s would rebel against all of this! + next_section_and_step: era_1960s_70s:step_1 + set_language: + content_blocks: + - "Language updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: era_1950s:step_1 + off_topic: + content_blocks: + - "Think about: After women proved they could do factory work, why would society want them in full skirts and heels again?" + next_section_and_step: era_1950s:step_1 + + - section_id: era_1960s_70s + title: "1960s-70s: Revolution & Expression" + steps: + - step_id: step_1 + title: Mod, Hippie, and Disco + content_blocks: + - "## The 1960s-70s: Fashion Revolution! ✌️🌼" + - "" + - "**The 1960s: Youth Rebellion**" + - "" + - "**Mod Fashion (Early 60s):**" + - "- **Mini skirts!** Mary Quant raised hemlines to mid-thigh (scandal!)" + - "- **Shift dresses** - simple, geometric, youthful" + - "- **Go-go boots** - white, knee-high" + - "- **Bold patterns** - geometric, colorful" + - "- **Twiggy** - thin, androgynous model became icon" + - "" + - "**Hippie Fashion (Late 60s-Early 70s):**" + - "- **Bell-bottoms and flares**" + - "- **Tie-dye, paisley, fringe**" + - "- **Long, natural hair** (men and women)" + - "- **Peasant blouses, maxi skirts**" + - "- **Peace symbols, flowers** - anti-war message in clothing" + - "- Rejection of mainstream 'establishment' fashion" + - "" + - "**The 1970s: Disco & Diversity**" + - "" + - "**Disco Era:**" + - "- **Platform shoes** - incredibly high!" + - "- **Jumpsuits** in shiny fabrics" + - "- **Hot pants** (very short shorts)" + - "- **Polyester everything**" + - "- **Studio 54** glamour" + - "" + - "**Punk Emerges (Late 70s):**" + - "- Ripped clothing, safety pins, DIY aesthetic" + - "- Anti-fashion as fashion" + - "- Vivienne Westwood and Malcolm McLaren" + - "" + - "**Key Theme:** Fashion became about IDENTITY and REBELLION" + question: The 1960s-70s saw more fashion diversity than ever before (mod, hippie, disco, punk). What does this variety tell you about society at that time? + tokens_for_ai: | + Analyzing connection between fashion diversity and social change. + + Look for understanding of: + - Individual expression becoming valued + - Counter-culture movements + - Rejection of conformity + - Social/political upheaval + - Youth culture power + + Categorize as: + - connects_to_freedom: Links fashion diversity to individual freedom/expression + - social_movements: Connects to civil rights, anti-war, counter-culture + - rebellion_theme: Notes rejection of conformity or establishment + - diversity_observation: Comments on variety and choice + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + Celebrate their analysis! + + Key themes: + - "Don't trust anyone over 30" - youth culture dominated + - Civil rights, women's rights, anti-war movements + - Fashion became a form of protest and identity + - You could tell someone's values from their clothes + - End of one-size-fits-all fashion + - Beginning of modern diversity in style + + Transition to how this continues... + buckets: + - connects_to_freedom + - social_movements + - rebellion_theme + - diversity_observation + - set_language + - off_topic + transitions: + connects_to_freedom: + ai_feedback: + tokens_for_ai: | + Perfect insight! + Yes - individual expression became paramount! + "Be yourself" was the message. + Fashion diversity reflected the belief everyone should be free to be different. + This era changed fashion forever - no going back to conformity! + metadata_add: + score: "n+1" + next_section_and_step: era_1980s_90s:step_1 + social_movements: + ai_feedback: + tokens_for_ai: | + Excellent connection to social movements! + Civil rights, feminism, anti-war protests all influenced fashion. + Hippies wore their politics (peace symbols, natural styles). + Punk was anti-establishment. + Fashion became a powerful form of protest! + metadata_add: + score: "n+1" + next_section_and_step: era_1980s_90s:step_1 + rebellion_theme: + ai_feedback: + tokens_for_ai: | + Exactly - rebellion against the conformist 1950s! + Young people rejected their parents' values and fashion. + Mini skirts, long hair, wild patterns - all shocking to the older generation. + Fashion became a generation gap battleground! + next_section_and_step: era_1980s_90s:step_1 + diversity_observation: + ai_feedback: + tokens_for_ai: | + Great observation! + For the first time, there wasn't ONE correct way to dress. + You could be mod, hippie, disco, preppy - all valid! + This diversity in fashion reflected a more diverse, pluralistic society. + next_section_and_step: era_1980s_90s:step_1 + set_language: + content_blocks: + - "Language updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: era_1960s_70s:step_1 + off_topic: + content_blocks: + - "Think about: When fashion becomes diverse, what does that say about society's values around conformity and individual expression?" + next_section_and_step: era_1960s_70s:step_1 + + - section_id: era_1980s_90s + title: "1980s-90s: Excess to Minimalism" + steps: + - step_id: step_1 + title: Power Dressing to Grunge + content_blocks: + - "## The 1980s: MORE IS MORE! 💼💎" + - "" + - "**Power Dressing:**" + - "- **Shoulder pads** - HUGE! (Women in the workplace needed to look powerful)" + - "- **Bold colors** - bright, neon, eye-catching" + - "- **Designer labels** showing - status symbols" + - "- **'Dynasty' and 'Dallas'** TV fashion influence" + - "- **Athletic wear as fashion** - leg warmers, leotards (Jane Fonda!)" + - "" + - "**Men's 1980s:**" + - "- Oversized suits with shoulder pads" + - "- Suspenders, bold ties" + - "- Miami Vice pastels" + - "" + - "**Youth Culture:**" + - "- Punk and New Wave (Mohawks, leather, chains)" + - "- Preppy (Ralph Lauren, Lacoste)" + - "- Hip-hop influence emerging (Adidas, gold chains, Kangol hats)" + - "" + - "---" + - "" + - "## The 1990s: Anti-Fashion Backlash 🎸" + - "" + - "**Grunge Revolution:**" + - "- **Reaction against 1980s excess**" + - "- **Flannel shirts, ripped jeans, combat boots**" + - "- **Thrift store aesthetic** - deliberately anti-glamorous" + - "- **Nirvana, Pearl Jam** - Seattle music scene influence" + - "- Messy, 'I don't care' attitude" + - "" + - "**Minimalism:**" + - "- **Calvin Klein, simple lines**" + - "- **'Heroin chic'** - Kate Moss" + - "- Neutral colors, slip dresses" + - "- Less is more (opposite of 80s)" + - "" + - "**Also Popular:**" + - "- Hip-hop baggy jeans, oversized everything" + - "- Girl Power/Spice Girls platform shoes" + - "- 'Friends' Rachel haircut influence" + - "- Tattoos and piercings going mainstream" + question: The 1990s grunge fashion was deliberately anti-glamorous (thrift store clothes, 'I don't care' attitude). Why do you think this style became popular after the flashy 1980s? + tokens_for_ai: | + Analyzing the cultural shift from 80s excess to 90s grunge. + + Look for: + - Backlash/reaction to 80s materialism + - Authenticity over image + - Economic factors (recession) + - Alternative/indie culture rise + - Rejection of superficiality + + Categorize as: + - backlash_insight: Recognizes reaction against 80s excess/materialism + - authenticity_theme: Notes desire for 'realness' or authenticity + - cultural_shift: Understands broader cultural change + - basic_answer: Notes the difference + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + Affirm their understanding! + + Key points: + - Backlash against 1980s materialism and excess + - Early 90s recession made flashy wealth seem tasteless + - Generation X rejected Baby Boomer values + - Desire for authenticity over image + - Music (grunge, alternative) influenced fashion + - "Selling out" was the worst insult + + Note how fashion reflects economic and cultural shifts. + buckets: + - backlash_insight + - authenticity_theme + - cultural_shift + - basic_answer + - set_language + - off_topic + transitions: + backlash_insight: + ai_feedback: + tokens_for_ai: | + Perfect analysis! + The 90s was absolutely a backlash against 80s greed and flash. + The recession made conspicuous consumption seem gross. + Grunge was anti-materialist - thrift stores over designer labels. + "Selling out" was the ultimate insult! + Fashion reflected a cultural rejection of superficiality. + metadata_add: + score: "n+1" + next_section_and_step: era_2000s_2010s:step_1 + authenticity_theme: + ai_feedback: + tokens_for_ai: | + Excellent point about authenticity! + The 90s valued 'real' over polished. + Grunge was about being yourself, not following trends. + Looking like you tried too hard was bad! + This anti-fashion became THE fashion. + metadata_add: + score: "n+1" + next_section_and_step: era_2000s_2010s:step_1 + cultural_shift: + ai_feedback: + tokens_for_ai: | + Great observation! + Culture shifted from 'greed is good' to alternative values. + Generation X rejected their parents' materialism. + Music, economics, and attitudes all changed. + Fashion always reflects these broader shifts! + next_section_and_step: era_2000s_2010s:step_1 + basic_answer: + ai_feedback: + tokens_for_ai: | + Good thinking! + The 90s rejected 80s excess. + People wanted authenticity and simplicity instead of flash. + Grunge reflected that cultural shift perfectly! + next_section_and_step: era_2000s_2010s:step_1 + set_language: + content_blocks: + - "Language updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: era_1980s_90s:step_1 + off_topic: + content_blocks: + - "Consider: After a decade of bright colors, designer labels, and excess, why would the opposite (thrift stores, 'I don't care') become cool?" + next_section_and_step: era_1980s_90s:step_1 + + - section_id: era_2000s_2010s + title: "2000s-2010s: Digital Age Fashion" + steps: + - step_id: step_1 + title: Fast Fashion and Social Media + content_blocks: + - "## The 2000s: Y2K & Fast Fashion 📱✨" + - "" + - "**Early 2000s Trends:**" + - "- **Low-rise jeans** (very low!)" + - "- **Velour tracksuits** (Juicy Couture)" + - "- **Trucker hats, Von Dutch**" + - "- **Ugg boots** everywhere" + - "- **'Bling'** - Paris Hilton, celebrity culture" + - "- **Skinny everything** - jeans, ties, scarves" + - "" + - "**Fast Fashion Explosion:**" + - "- H&M, Zara, Forever 21 dominate" + - "- Runway trends to stores in weeks" + - "- Cheap, disposable fashion" + - "- More consumption than ever" + - "" + - "---" + - "" + - "## The 2010s: Social Media Changes Everything 📸" + - "" + - "**Instagram Fashion:**" + - "- **Athleisure** - yoga pants everywhere (lululemon)" + - "- **Fast fashion faster** - trend cycles in days" + - "- **Influencer culture** - bloggers become more powerful than magazines" + - "- **'Instagram-worthy'** outfits" + - "- **Festival fashion** - Coachella as fashion event" + - "" + - "**Normcore (2010s):**" + - "- Deliberately boring, average clothes" + - "- Reaction to constant trend cycles" + - "- Steve Jobs turtleneck aesthetic" + - "" + - "**Streetwear Boom:**" + - "- Supreme, Off-White, sneaker culture" + - "- Hoodies become high fashion" + - "- Collaborations (designer x streetwear)" + - "- Hype culture and limited drops" + - "" + - "**Body Positivity Begins:**" + - "- Plus-size models gain visibility" + - "- Diversity slowly increasing" + - "- Challenging beauty standards" + question: Social media (Instagram, TikTok) dramatically changed fashion in the 2010s. How do you think social media affects what people wear compared to earlier eras? + tokens_for_ai: | + Analyzing social media's impact on fashion. + + Look for: + - Speed of trends + - Influence of regular people/influencers + - Constant exposure/comparison + - Democratization of fashion + - Pressure to constantly have new looks + + Categorize as: + - speed_and_trends: Notes faster trend cycles, constant newness + - democratization: Notes regular people can influence, not just designers/magazines + - pressure_awareness: Mentions pressure, comparison, or negative aspects + - influence_shift: Notes shift from magazines/designers to influencers/individuals + - basic_observation: Notes social media changed things + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + Validate their media literacy! + + Key impacts of social media on fashion: + - Trends move at light speed (viral in hours) + - Anyone can be a fashion influencer + - Constant visual exposure = pressure to look good + - FOMO and comparison culture + - But also: more diverse representation + - Direct-to-consumer brands + - Democratization but also anxiety + + Transition to current era (2020s)... + buckets: + - speed_and_trends + - democratization + - pressure_awareness + - influence_shift + - basic_observation + - set_language + - off_topic + transitions: + speed_and_trends: + ai_feedback: + tokens_for_ai: | + Exactly right! + Trends that used to last years now last weeks or days. + TikTok can make something viral overnight. + Fast fashion tries to keep up - environmental disaster! + The constant newness creates pressure and waste. + metadata_add: + score: "n+1" + next_section_and_step: era_2020s:step_1 + democratization: + ai_feedback: + tokens_for_ai: | + Great insight! + Social media democratized fashion influence. + No longer just Vogue telling us what to wear! + Regular people, influencers, anyone can set trends. + More diverse voices and styles than ever. + Power shifted from gatekeepers to the crowd! + metadata_add: + score: "n+1" + next_section_and_step: era_2020s:step_1 + pressure_awareness: + ai_feedback: + tokens_for_ai: | + Important observation! + Social media creates constant comparison and pressure. + Everyone curates their best looks online. + FOMO about trends, outfits, appearing 'on point.' + This has mental health impacts, especially for young people. + Fashion should be fun, not stressful! + metadata_add: + score: "n+1" + next_section_and_step: era_2020s:step_1 + influence_shift: + ai_feedback: + tokens_for_ai: | + Perfect analysis! + Influencers replaced fashion magazines as authorities. + A YouTuber with a million followers has more impact than Vogue! + This shifted power in the fashion industry. + More democratic, but also more commercial in new ways. + next_section_and_step: era_2020s:step_1 + basic_observation: + ai_feedback: + tokens_for_ai: | + True! + Social media made trends move faster and gave regular people fashion influence. + Instagram and TikTok changed the whole industry! + next_section_and_step: era_2020s:step_1 + set_language: + content_blocks: + - "Language updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: era_2000s_2010s:step_1 + off_topic: + content_blocks: + - "Think about how seeing everyone's outfits constantly on Instagram or TikTok might change fashion compared to just seeing magazines once a month." + next_section_and_step: era_2000s_2010s:step_1 + + - section_id: era_2020s + title: "2020s: Now and Future" + steps: + - step_id: step_1 + title: Fashion Today and Tomorrow + content_blocks: + - "## The 2020s: Sustainability, Inclusivity, Individuality 🌍💚" + - "" + - "**The Pandemic Effect (2020-2021):**" + - "- **Comfort became king** - loungewear, sweats, pajamas all day" + - "- **'Zoom tops'** - dressed up top, casual bottom" + - "- **Masks as fashion accessories**" + - "- Working from home changed what we wear" + - "" + - "**Current Major Trends (2020-2025):**" + - "" + - "**1. Sustainability & Ethics:**" + - "- Backlash against fast fashion waste" + - "- Thrifting, vintage, secondhand cool again" + - "- Rental fashion platforms" + - "- Transparent supply chains" + - "- Upcycling and repair becoming trendy" + - "" + - "**2. Radical Inclusivity:**" + - "- Plus-size fashion finally mainstream" + - "- Adaptive clothing for disabilities" + - "- Gender-neutral fashion growing" + - "- Diverse models and representation" + - "- Beauty standards expanding" + - "" + - "**3. Extreme Individuality:**" + - "- Mix of ALL eras (Y2K revival, 90s, 80s, cottagecore)" + - "- Micro-trends everywhere" + - "- Personal style over following trends" + - "- Maximalism AND minimalism both valid" + - "- Algorithm-driven personal style" + - "" + - "**4. Technology Integration:**" + - "- Digital fashion (NFTs, gaming skins)" + - "- AR try-ons" + - "- 3D printed clothing" + - "- Smart fabrics" + - "" + - "**5. Comfort & Function:**" + - "- Athleisure still dominant" + - "- Practical, versatile pieces" + - "- 'Dopamine dressing' (colors that make you happy)" + - "- Wellness integrated with fashion" + question: After learning this history, where do you think fashion is heading in the next 10-20 years? What changes or trends do you predict? + tokens_for_ai: | + Student predicting future fashion based on historical patterns. + + Look for: + - Sustainability/environmental focus + - Technology integration + - Continued inclusivity + - Personalization + - Reaction to current trends + + Categorize as: + - sustainability_focus: Predicts environmental/ethical fashion + - tech_integration: Mentions technology, digital fashion, innovation + - inclusivity_expansion: Predicts more diversity and accessibility + - individualism_theme: Predicts personal expression over trends + - creative_prediction: Unique or interesting ideas + - general_future: Mentions future without specific predictions + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + Engage with their predictions enthusiastically! + + Validate plausible predictions. + Add expert predictions if appropriate: + - Circular fashion (rental, resale, repair) + - Lab-grown materials + - AI-personalized recommendations + - Even more gender-neutral options + - Continued vintage/thrift dominance + - Local/small brands vs global corporations + + Celebrate their future thinking! + buckets: + - sustainability_focus + - tech_integration + - inclusivity_expansion + - individualism_theme + - creative_prediction + - general_future + - set_language + - off_topic + transitions: + sustainability_focus: + ai_feedback: + tokens_for_ai: | + Excellent prediction! + Sustainability is THE major trend of the future. + Gen Z demands ethical fashion. + Experts predict circular economy - rental, resale, repair! + Lab-grown materials, zero-waste design. + Fast fashion's days may be numbered! + metadata_add: + score: "n+1" + activity_completed: "true" + next_section_and_step: conclusion:step_1 + tech_integration: + ai_feedback: + tokens_for_ai: | + Great future thinking! + Technology will absolutely transform fashion! + Digital clothing, virtual try-ons, AI personalization. + 3D printing custom garments at home? + Smart fabrics that adapt to temperature? + The possibilities are exciting! + metadata_add: + activity_completed: "true" + next_section_and_step: conclusion:step_1 + inclusivity_expansion: + ai_feedback: + tokens_for_ai: | + Wonderful prediction! + Inclusivity will only grow. + Every body, every gender, every ability represented. + Fashion for everyone, not just one ideal type. + This is one of the most positive trends! + metadata_add: + activity_completed: "true" + next_section_and_step: conclusion:step_1 + individualism_theme: + ai_feedback: + tokens_for_ai: | + Insightful prediction! + The future is hyper-personalized style. + Algorithms that understand YOUR specific taste. + No more 'everyone wearing the same thing.' + Fashion reflecting infinite individual identities! + metadata_add: + activity_completed: "true" + next_section_and_step: conclusion:step_1 + creative_prediction: + ai_feedback: + tokens_for_ai: | + Creative thinking! + Reference their specific prediction. + Discuss plausibility and how it might happen. + Celebrate their imagination about fashion's future! + metadata_add: + activity_completed: "true" + next_section_and_step: conclusion:step_1 + general_future: + ai_feedback: + tokens_for_ai: | + The future of fashion is exciting! + Based on history: sustainability, technology, and inclusivity seem key. + But fashion always surprises us! + metadata_add: + activity_completed: "true" + next_section_and_step: conclusion:step_1 + set_language: + content_blocks: + - "Language updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: era_2020s:step_1 + off_topic: + content_blocks: + - "Based on the patterns you've seen through history, what do you think fashion will look like in 2035 or 2040?" + next_section_and_step: era_2020s:step_1 + + - section_id: conclusion + title: Fashion History Complete + steps: + - step_id: step_1 + title: Congratulations, Fashion Historian! + content_blocks: + - "## Congratulations, Fashion Historian! 🎓👗⏰" + - "" + - "**You've journeyed through 225 years of fashion!**" + - "" + - "**What You've Learned:**" + - "✓ 1800s: Restrictive Victorian corsets reflected women's limited rights" + - "✓ 1920s: Flappers liberated fashion along with suffrage" + - "✓ 1940s: War made practical clothing necessary for women" + - "✓ 1950s: Post-war push for traditional femininity" + - "✓ 1960s-70s: Fashion became protest and individual expression" + - "✓ 1980s: Excess, power dressing, status symbols" + - "✓ 1990s: Grunge rejected materialism" + - "✓ 2000s-2010s: Fast fashion and social media acceleration" + - "✓ 2020s: Sustainability, inclusivity, technology" + - "" + - "**The Big Lesson:**" + - "Fashion is NEVER just about clothes!" + - "" + - "Fashion reflects:" + - "- Social and political movements" + - "- Economic conditions" + - "- Technology and innovation" + - "- Cultural values and rebellion" + - "- Gender politics and identity" + - "- Individual and collective expression" + - "" + - "**Every outfit tells a story about its time!**" + - "" + - "**Your Fashion Journey Continues:**" + - "- Look at historical photos with new eyes" + - "- Consider what current fashion says about today" + - "- Think about your own style choices and what they express" + - "- Maybe explore vintage fashion from your favorite era!" + - "" + - "**Fashion is history you can WEAR! 💫**" From e4ab13ae789a52a8650970a5c9c6d9274ff87cb1 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 9 Nov 2025 15:09:50 +0000 Subject: [PATCH 3/7] Fix pedagogical issue: Don't show code examples before asking students to write code PROBLEM: activity37 was showing complete code examples in Python, JavaScript, Java, and C++ BEFORE asking students to write code themselves. This turns learning into copy-paste practice. FIXED: - Hello World section: Removed multi-language code examples from content_blocks - Variables section: Removed multi-language code examples from content_blocks - Now explains CONCEPTS (what, why, how languages differ) without showing syntax - Code examples remain in AI feedback for when students struggle or ask for help PEDAGOGICAL APPROACH: 1. Explain the concept (stdout, variables, etc.) 2. Explain language differences conceptually (dynamic vs static typing) 3. Ask students to TRY writing code in THEIR language 4. Provide language-specific examples in AI FEEDBACK if they struggle This way students actually have to THINK and LEARN, not just copy. UPDATED CLAUDE.md: - Added new pitfall: "Showing answers before questions" - Guidance: Explain concepts in content_blocks, provide code examples in ai_feedback Still validates perfectly with zero errors/warnings. --- CLAUDE.md | 1 + .../activity37-programming-languages.yaml | 70 +++++++------------ 2 files changed, 26 insertions(+), 45 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 2e313f3..ee65fb4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -694,6 +694,7 @@ feedback_tokens_for_ai: | | **Generic feedback** | "Good job!" isn't helpful | Reference specific parts of their answer | | **Dead-end paths** | User stuck, can't progress | Always provide a way forward (even if it's restarting) | | **Ignoring the rubric** | Global `tokens_for_ai_rubric` tells AI how to evaluate | Define it for consistency across steps | +| **Showing answers before questions** | Users copy-paste instead of learning | Explain CONCEPTS in content_blocks, provide CODE EXAMPLES only in ai_feedback | ### Activity Development Workflow diff --git a/research/activity37-programming-languages.yaml b/research/activity37-programming-languages.yaml index 025ef21..a5fe49e 100644 --- a/research/activity37-programming-languages.yaml +++ b/research/activity37-programming-languages.yaml @@ -174,30 +174,20 @@ sections: - '' - 'This is why understanding stdout matters - it''s not just "printing to the screen," it''s sending data to a stream that can go anywhere!' - '' - - '### How Different Languages Display Output' - - 'Every programming language has its own syntax, but they all accomplish the same goal. Here are examples across different languages:' + - '### How Languages Display Output' - '' - - '**Python:** Uses `print()` function' - - '```python' - - 'print("Hello, World!")' - - '```' + - 'Every programming language has its own syntax for displaying output to stdout:' + - '- Some use a `print()` function' + - '- Some use `console.log()`' + - '- Some use methods like `System.out.println()`' + - '- Some use stream operators like `<<`' - '' - - '**JavaScript:** Uses `console.log()` function' - - '```javascript' - - 'console.log("Hello, World!");' - - '```' + - 'Despite different syntax, they all accomplish the same goal: sending text to stdout.' - '' - - '**Java:** Uses `System.out.println()` method' - - '```java' - - 'System.out.println("Hello, World!");' - - '```' + - '**Important Concept:**' + - 'Text in quotes (like `"Hello, World!"`) is called a **string** - it represents text data that you want to display.' - '' - - '**C++:** Uses `std::cout` stream' - - '```cpp' - - 'std::cout << "Hello, World!" << std::endl;' - - '```' - - '' - - '**Key Concept:** Notice that while the syntax differs, each language has a way to send text to stdout. The quotes around "Hello, World!" indicate it''s a **string** (text data).' + - 'Now you''ll figure out how YOUR chosen language does it!' - '' - '### Now It''s Your Turn!' question: How do you display 'Hello, World!' to stdout in your chosen language? Write the complete code. @@ -464,36 +454,26 @@ sections: - '**Good names:** `user_name`, `total_score`, `isActive`, `playerHealth`' - '**Bad names:** `x`, `temp`, `asdf`, `thing1`' - '' - - '### How to Create Variables in Different Languages' + - '### How Languages Handle Variables' - '' - - '**Python (dynamically typed):**' - - '```python' - - 'name = "Alice" # Create variable and assign value' - - 'print(name) # Display the variable''s value' - - '```' + - 'Every programming language has its own syntax for creating variables, but they all follow the same basic pattern:' + - '1. Give the variable a name' + - '2. Use an assignment operator (usually `=`)' + - '3. Provide a value' - '' - - '**JavaScript (dynamically typed):**' - - '```javascript' - - 'let name = "Alice"; // Declare with let' - - 'console.log(name); // Display' - - '```' + - '**Important Language Difference:**' - '' - - '**Java (statically typed):**' - - '```java' - - 'String name = "Alice"; // Must specify type' - - 'System.out.println(name); // Display' - - '```' + - '**Dynamically typed languages** (like Python, JavaScript, Ruby):' + - '- You just name the variable and assign a value' + - '- The language automatically figures out the type' + - '- Simpler syntax, more flexible' - '' - - '**C++ (statically typed):**' - - '```cpp' - - 'std::string name = "Alice"; // Must specify type' - - 'std::cout << name << std::endl; // Display' - - '```' + - '**Statically typed languages** (like Java, C++, C#, Go):' + - '- You must specify the data type when creating a variable' + - '- Example: declare that `name` will store a String' + - '- More verbose, but catches type errors early' - '' - - '### Key Differences' - - '**Dynamically typed languages** (Python, JavaScript, Ruby): You don''t declare the type. The language figures it out automatically.' - - '' - - '**Statically typed languages** (Java, C++, C#, Go): You must specify the type (String, int, etc.) when creating a variable.' + - 'You''ll use YOUR language''s specific syntax to create variables!' - '' - '### The Assignment Operator' - 'The `=` sign is the **assignment operator**. It means "assign the value on the right to the variable on the left."' From 31e357e8bfc1a8cfa7d192281d84b5a634ff9915 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 9 Nov 2025 15:25:04 +0000 Subject: [PATCH 4/7] Add statistics and game theory 101 activities plus pedagogical fixes --- research/activity40-statistics-101.yaml | 786 +++++++++++++++++++++++ research/activity41-game-theory-101.yaml | 740 +++++++++++++++++++++ 2 files changed, 1526 insertions(+) create mode 100644 research/activity40-statistics-101.yaml create mode 100644 research/activity41-game-theory-101.yaml diff --git a/research/activity40-statistics-101.yaml b/research/activity40-statistics-101.yaml new file mode 100644 index 0000000..5fc09d9 --- /dev/null +++ b/research/activity40-statistics-101.yaml @@ -0,0 +1,786 @@ +default_max_attempts_per_step: 3 +classifier_model: "MODEL_1" +feedback_model: "MODEL_1" +tokens_for_ai_rubric: | + Evaluate the student's understanding of basic statistical concepts. + + Consider: + - Grasp of central tendency (mean, median, mode) + - Understanding of variation and spread + - Ability to interpret data + - Recognition of distributions + - Practical application of concepts + + Provide clear explanations with real-world examples. + +sections: + - section_id: introduction + title: Welcome to Statistics + steps: + - step_id: welcome + title: Why Statistics Matters + content_blocks: + - "# Statistics 101: Making Sense of Data 📊" + - "" + - "**Welcome to the world of statistics!**" + - "" + - "Statistics helps us:" + - "- Understand patterns in data" + - "- Make informed decisions" + - "- Test hypotheses scientifically" + - "- Predict future outcomes" + - "- Avoid being fooled by randomness" + - "" + - "**You'll learn:**" + - "✓ Measures of central tendency (mean, median, mode)" + - "✓ Measures of spread (range, variance, standard deviation)" + - "✓ Probability basics" + - "✓ Distributions and what they mean" + - "✓ How to interpret data" + - "" + - "**Real-world applications:**" + - "- Medicine (clinical trial results)" + - "- Business (sales forecasting)" + - "- Sports (player performance)" + - "- Science (experimental data)" + - "- Everyday decisions (risk assessment)" + question: Ready to learn how to understand data and make better decisions? + tokens_for_ai: | + Accept positive responses as 'ready'. + Language preference as 'set_language'. + Otherwise 'off_topic'. + buckets: + - ready + - set_language + - off_topic + transitions: + ready: + content_blocks: + - "Excellent! Let's start with the basics of describing data! 📈" + next_section_and_step: central_tendency:step_1 + set_language: + content_blocks: + - "Language preference updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: introduction:welcome + off_topic: + content_blocks: + - "Let's learn statistics together! Are you ready to begin?" + counts_as_attempt: false + next_section_and_step: introduction:welcome + + - section_id: central_tendency + title: Describing Data - Central Tendency + steps: + - step_id: step_1 + title: The Center of Data + content_blocks: + - "## Central Tendency: Finding the 'Middle' 📍" + - "" + - "When we have a dataset, we often want to describe it with a single number that represents the 'typical' or 'central' value." + - "" + - "**Three measures of central tendency:**" + - "" + - "**1. Mean (Average)**" + - "- Sum all values and divide by the count" + - "- Most commonly used" + - "- Sensitive to extreme values (outliers)" + - "- Example: Test scores 80, 85, 90, 95 → Mean = (80+85+90+95)/4 = 87.5" + - "" + - "**2. Median (Middle Value)**" + - "- The middle number when data is sorted" + - "- Not affected by outliers" + - "- Better for skewed data" + - "- Example: Salaries $30k, $35k, $40k, $45k, $200k → Median = $40k" + - "" + - "**3. Mode (Most Frequent)**" + - "- The value that appears most often" + - "- Useful for categorical data" + - "- Can have multiple modes or no mode" + - "- Example: Shoe sizes 7, 8, 8, 8, 9, 10 → Mode = 8" + - "" + - "**When to use which:**" + - "- Mean: Normally distributed data without outliers" + - "- Median: Skewed data or data with outliers (like income)" + - "- Mode: Categorical data or finding most common value" + question: "You have exam scores: 60, 70, 75, 80, 85, 90, 95. What is the median score?" + tokens_for_ai: | + The median is the middle value when sorted. + Scores: 60, 70, 75, 80, 85, 90, 95 (7 values) + Middle value (4th position) = 80 + + Categorize as: + - correct: Says 80 or "eighty" + - calculated_mean: Says 79.3 or ~79 (they calculated the mean instead) + - close: Says 75 or 85 (one position off) + - confused: Incorrect answer showing confusion + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + If correct: + - Praise them! Explain why 80 is the middle value. + - Note that with odd numbers, median is straightforward. + + If they calculated mean: + - Good effort but that's the mean! + - Explain median is the MIDDLE value when sorted, not the average. + + If close or confused: + - Show the sorted list: 60, 70, 75, [80], 85, 90, 95 + - The middle position (4th out of 7) is 80. + buckets: + - correct + - calculated_mean + - close + - confused + - set_language + - off_topic + transitions: + correct: + ai_feedback: + tokens_for_ai: | + Perfect! 80 is the median - the middle value. + With 7 values, the 4th position is the center. + Median is great because outliers don't affect it! + metadata_add: + score: "n+2" + concepts_mastered: "n+1" + next_section_and_step: central_tendency:step_2 + calculated_mean: + ai_feedback: + tokens_for_ai: | + That's the mean (average), not the median! + Median = middle value when sorted. + For 60,70,75,[80],85,90,95 → median is 80. + The mean would be all values summed divided by 7. + metadata_add: + score: "n+1" + next_section_and_step: central_tendency:step_2 + close: + ai_feedback: + tokens_for_ai: | + Close! You're near the middle. + Sort the values: 60, 70, 75, [80], 85, 90, 95 + The exact middle (4th position out of 7) is 80. + next_section_and_step: central_tendency:step_1 + confused: + content_blocks: + - "The median is the MIDDLE value when you sort the numbers from smallest to largest." + - "With 7 values, the 4th number is in the middle." + next_section_and_step: central_tendency:step_1 + set_language: + content_blocks: + - "Language updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: central_tendency:step_1 + off_topic: + content_blocks: + - "Let's find the median! Sort the scores and identify the middle value." + next_section_and_step: central_tendency:step_1 + + - step_id: step_2 + title: Mean vs Median with Outliers + content_blocks: + - "## The Power of Median: Handling Outliers 🎯" + - "" + - "**Why median matters: The salary example**" + - "" + - "Imagine a small company with 5 employees and their salaries:" + - "- Employee A: $40,000" + - "- Employee B: $45,000" + - "- Employee C: $50,000" + - "- Employee D: $55,000" + - "- CEO: $500,000" + - "" + - "**Mean salary:** ($40k + $45k + $50k + $55k + $500k) / 5 = $138,000" + - "**Median salary:** $50,000 (the middle value)" + - "" + - "**Which better represents the 'typical' employee salary?**" + - "The median! The mean is dragged up by the CEO's outlier salary." + - "" + - "**This is why:**" + - "- Median home prices are reported (not mean)" + - "- Median household income is used (not mean)" + - "- Outliers don't distort the median" + - "" + - "**When one extreme value can mislead, use median!**" + question: "A neighborhood has 6 home prices: $200k, $210k, $220k, $230k, $240k, and $2,000k. If someone says 'the average home price is $516k,' why might that be misleading? What would better represent typical home prices?" + tokens_for_ai: | + They should recognize that: + - The $2 million home is an outlier + - Mean is misleading ($516k) + - Median would be better (between $220k and $230k = $225k) + + Categorize as: + - excellent_understanding: Mentions outlier skewing mean, median better + - understands_outlier: Recognizes the expensive house is the problem + - suggests_median: Says median without explaining why + - partial_understanding: On the right track but incomplete + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + Validate their understanding of outliers affecting mean! + + Key points: + - The $2M home is an outlier (way higher than others) + - Mean gets pulled up to $516k (not representative) + - Median would be $225k (between 220 and 230) - much more typical + - This is why real estate uses median prices! + + Praise their critical thinking about statistics. + buckets: + - excellent_understanding + - understands_outlier + - suggests_median + - partial_understanding + - set_language + - off_topic + transitions: + excellent_understanding: + ai_feedback: + tokens_for_ai: | + Brilliant analysis! + Yes - the $2M outlier drags the mean to $516k, misleading! + The median ($225k) better represents typical homes. + This is exactly why statistics literacy matters! + metadata_add: + score: "n+2" + concepts_mastered: "n+1" + next_section_and_step: spread:step_1 + understands_outlier: + ai_feedback: + tokens_for_ai: | + Exactly! The $2M home is an outlier. + It pulls the mean to $516k, but most homes are $200-240k. + The median ($225k) would be more representative. + Great critical thinking! + metadata_add: + score: "n+1" + next_section_and_step: spread:step_1 + suggests_median: + ai_feedback: + tokens_for_ai: | + Good instinct - median is better here! + Why? The $2M outlier skews the mean to $516k. + But the median ($225k) represents the typical home price. + Outliers don't affect median - that's its power! + next_section_and_step: spread:step_1 + partial_understanding: + ai_feedback: + tokens_for_ai: | + You're on the right track! + The key: one $2M home among $200-240k homes. + This outlier pulls mean to $516k (misleading). + Median ($225k) better shows typical prices. + next_section_and_step: spread:step_1 + set_language: + content_blocks: + - "Language updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: central_tendency:step_2 + off_topic: + content_blocks: + - "Think about: Does $516k accurately represent what most homes in this neighborhood cost?" + next_section_and_step: central_tendency:step_2 + + - section_id: spread + title: Measuring Spread - Variability + steps: + - step_id: step_1 + title: Understanding Variability + content_blocks: + - "## Spread: How Much Do Values Vary? 📏" + - "" + - "Central tendency tells us the 'middle,' but doesn't tell the full story." + - "" + - "**Consider two classes:**" + - "- Class A scores: 80, 82, 78, 81, 79 (mean = 80)" + - "- Class B scores: 50, 70, 80, 90, 110 (mean = 80)" + - "" + - "Same mean, VERY different distributions!" + - "Class A is consistent. Class B is all over the place." + - "" + - "**Measures of Spread:**" + - "" + - "**1. Range**" + - "- Maximum value minus minimum value" + - "- Simple but sensitive to outliers" + - "- Class A: 82 - 78 = 4" + - "- Class B: 110 - 50 = 60" + - "" + - "**2. Variance**" + - "- Average of squared differences from mean" + - "- Measures how spread out values are" + - "- Larger variance = more spread" + - "" + - "**3. Standard Deviation (SD)**" + - "- Square root of variance" + - "- Same units as original data (easier to interpret)" + - "- Most commonly used measure of spread" + - "" + - "**Why spread matters:**" + - "- Quality control (consistency in manufacturing)" + - "- Risk assessment (investment volatility)" + - "- Performance evaluation (consistency vs streaky)" + - "- Research (reliability of measurements)" + question: "Two basketball players both average 20 points per game. Player A's scores: 18, 19, 20, 21, 22. Player B's scores: 5, 10, 20, 30, 35. Which player is more consistent, and why does that matter?" + tokens_for_ai: | + Player A is more consistent (low spread/variance). + Player B is inconsistent/volatile (high spread). + + Look for understanding that: + - Player A has consistent performance (small variation) + - Player B is unpredictable (large variation) + - Consistency matters for reliability/strategy + + Categorize as: + - excellent_answer: Identifies Player A as consistent AND explains why it matters + - identifies_player_a: Correctly says Player A is more consistent + - identifies_inconsistency: Recognizes the difference in variability + - basic_answer: Mentions one player without explaining + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + Affirm their understanding of consistency/spread! + + Key points: + - Player A: very consistent (range 18-22, low variation) + - Player B: unpredictable (range 5-35, high variation) + - Consistency matters: reliable performance, easier to plan around + - Player B might have higher ceiling but less reliable + + Connect to real sports analysis and standard deviation concept. + buckets: + - excellent_answer + - identifies_player_a + - identifies_inconsistency + - basic_answer + - set_language + - off_topic + transitions: + excellent_answer: + ai_feedback: + tokens_for_ai: | + Perfect analysis! + Player A: 18-22 (consistent, low spread). + Player B: 5-35 (volatile, high spread). + Consistency means reliability - you know what to expect! + This is what standard deviation measures! + metadata_add: + score: "n+2" + concepts_mastered: "n+1" + next_section_and_step: probability:step_1 + identifies_player_a: + ai_feedback: + tokens_for_ai: | + Correct! Player A is much more consistent. + Range: A is 18-22 (4 points), B is 5-35 (30 points!). + Low spread = predictable performance. + High spread = unpredictable, risky. + That's what measuring spread tells us! + metadata_add: + score: "n+1" + next_section_and_step: probability:step_1 + identifies_inconsistency: + ai_feedback: + tokens_for_ai: | + Good observation about the difference! + Player A varies 18-22 (tight, consistent). + Player B varies 5-35 (wild, unpredictable). + Consistency = reliability. This is why we measure spread! + next_section_and_step: probability:step_1 + basic_answer: + ai_feedback: + tokens_for_ai: | + Let's look at the ranges: + Player A: 18, 19, 20, 21, 22 (very tight - consistent!) + Player B: 5, 10, 20, 30, 35 (all over - inconsistent!) + Consistency means you can rely on them. Spread measures this! + next_section_and_step: probability:step_1 + set_language: + content_blocks: + - "Language updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: spread:step_1 + off_topic: + content_blocks: + - "Compare the ranges: Player A (18-22) vs Player B (5-35). Who's more predictable?" + next_section_and_step: spread:step_1 + + - section_id: probability + title: Probability Basics + steps: + - step_id: step_1 + title: Understanding Probability + content_blocks: + - "## Probability: Quantifying Uncertainty 🎲" + - "" + - "**What is probability?**" + - "A measure of how likely something is to happen." + - "" + - "**Probability scale:**" + - "- 0 = Impossible (0%)" + - "- 0.5 = Even chance (50%)" + - "- 1 = Certain (100%)" + - "" + - "**Basic probability formula:**" + - "P(event) = (Number of favorable outcomes) / (Total possible outcomes)" + - "" + - "**Example: Fair die**" + - "- P(rolling a 3) = 1/6 ≈ 0.167 (16.7%)" + - "- P(rolling even) = 3/6 = 0.5 (50%)" + - "- P(rolling 1-6) = 6/6 = 1 (100%)" + - "" + - "**Key concepts:**" + - "" + - "**Independent events:**" + - "- One doesn't affect the other" + - "- Coin flips, die rolls" + - "- P(heads then heads) = 0.5 × 0.5 = 0.25" + - "" + - "**Dependent events:**" + - "- One affects the probability of the other" + - "- Drawing cards without replacement" + - "" + - "**Common misconceptions:**" + - "- Gambler's fallacy: 'It's due!' (No - each event is independent)" + - "- Hot hand fallacy: Past streaks predict future (they don't in random events)" + question: "You flip a fair coin 5 times and get heads every time. What's the probability the 6th flip is heads? Why?" + tokens_for_ai: | + Correct answer: 50% or 0.5 or 1/2 + + Key understanding: Each flip is INDEPENDENT. + Past flips don't affect future flips. + + Common wrong answer: "It's more likely to be tails" (gambler's fallacy) + + Categorize as: + - correct_with_reasoning: Says 50% AND explains independence + - correct_answer: Says 50% without full explanation + - gamblers_fallacy: Says tails is more likely because "it's due" + - pattern_thinking: Thinks the pattern will continue + - confused: Other incorrect reasoning + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + If correct: + - Excellent! Each flip is independent. + - Past results don't affect future flips. + - The coin has no "memory" - always 50/50. + + If gambler's fallacy: + - Common misconception! This is the "gambler's fallacy." + - Each flip is independent - past doesn't affect future. + - It's still 50/50, even after 100 heads in a row! + - The coin doesn't "owe" you tails. + + Explain independence clearly. + buckets: + - correct_with_reasoning + - correct_answer + - gamblers_fallacy + - pattern_thinking + - confused + - set_language + - off_topic + transitions: + correct_with_reasoning: + ai_feedback: + tokens_for_ai: | + Perfect understanding! + Each coin flip is independent - past doesn't affect future. + The coin has no memory. Always 50/50! + You've avoided the gambler's fallacy - great! + metadata_add: + score: "n+2" + concepts_mastered: "n+1" + next_section_and_step: distributions:step_1 + correct_answer: + ai_feedback: + tokens_for_ai: | + Correct - still 50%! + Why? Each flip is INDEPENDENT. + Past flips don't affect future flips. + The coin doesn't "remember" or "balance out." + Great job avoiding the gambler's fallacy! + metadata_add: + score: "n+1" + next_section_and_step: distributions:step_1 + gamblers_fallacy: + ai_feedback: + tokens_for_ai: | + Common misconception! This is the "gambler's fallacy." + Each flip is INDEPENDENT - the coin has no memory. + Past flips don't affect future flips. + It's still 50/50, even after 1000 heads! + The coin doesn't "owe" you tails. + next_section_and_step: probability:step_1 + pattern_thinking: + ai_feedback: + tokens_for_ai: | + The streak feels meaningful, but it's not! + Each flip is independent - 50/50 every time. + Past results don't predict future with fair coins. + Random sequences often have "patterns" but they're meaningless. + next_section_and_step: probability:step_1 + confused: + content_blocks: + - "Key concept: INDEPENDENCE" + - "Each coin flip is independent - past flips don't affect future flips." + - "A fair coin always has 50% chance of heads, regardless of history." + next_section_and_step: probability:step_1 + set_language: + content_blocks: + - "Language updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: probability:step_1 + off_topic: + content_blocks: + - "Think: Does the coin 'remember' previous flips? Are they independent events?" + next_section_and_step: probability:step_1 + + - section_id: distributions + title: Understanding Distributions + steps: + - step_id: step_1 + title: The Normal Distribution + content_blocks: + - "## The Normal Distribution: Nature's Pattern 📊" + - "" + - "**The bell curve (normal distribution):**" + - "The most important distribution in statistics!" + - "" + - "**Characteristics:**" + - "- Symmetric, bell-shaped" + - "- Mean = Median = Mode (at the center)" + - "- Most data near the mean" + - "- Tails extend infinitely (but rarely reach extremes)" + - "" + - "**The 68-95-99.7 Rule (Empirical Rule):**" + - "- 68% of data within 1 standard deviation of mean" + - "- 95% of data within 2 standard deviations" + - "- 99.7% of data within 3 standard deviations" + - "" + - "**Example: IQ scores**" + - "- Mean = 100, Standard Deviation = 15" + - "- 68% of people: IQ between 85-115" + - "- 95% of people: IQ between 70-130" + - "- 99.7% of people: IQ between 55-145" + - "" + - "**Why normal distribution matters:**" + - "- Many natural phenomena follow it (height, measurement errors)" + - "- Central Limit Theorem (averages tend toward normal)" + - "- Foundation for many statistical tests" + - "- Allows predictions and probability calculations" + - "" + - "**Real-world examples:**" + - "- Test scores, heights, blood pressure, measurement errors" + question: "SAT scores are normally distributed with mean 1000 and standard deviation 200. Using the 68-95-99.7 rule, approximately what percentage of students score between 800 and 1200?" + tokens_for_ai: | + 800 to 1200 is mean (1000) ± 1 standard deviation (200). + 68% of data falls within 1 SD of the mean. + + Correct answer: 68% (or approximately 68%, or about 2/3) + + Categorize as: + - correct: Says 68% or approximately 68% + - close: Says 66% or 70% (reasonably close) + - says_95: Says 95% (confused 1 SD with 2 SD) + - unclear_reasoning: Wrong answer showing confusion + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + If correct: + - Excellent! 800-1200 is 1000 ± 200 (1 SD). + - 68% of data within 1 SD of mean. + - You've mastered the empirical rule! + + If says 95%: + - Close reasoning! But 95% is for 2 SDs. + - 800-1200 is only 1 SD (200 points) from mean. + - 1 SD = 68%, 2 SDs = 95%, 3 SDs = 99.7% + + Explain the calculation clearly. + buckets: + - correct + - close + - says_95 + - unclear_reasoning + - set_language + - off_topic + transitions: + correct: + ai_feedback: + tokens_for_ai: | + Perfect! 800-1200 is mean ± 1 SD. + 1 SD = 68% of data. + You understand the empirical rule! + This is fundamental for interpreting normal distributions! + metadata_add: + score: "n+2" + concepts_mastered: "n+1" + next_section_and_step: conclusion:step_1 + close: + ai_feedback: + tokens_for_ai: | + Very close! The exact answer is 68%. + 800-1200 = 1000 ± 200 (1 standard deviation). + The 68-95-99.7 rule: 68% within 1 SD. + Great understanding of the concept! + metadata_add: + score: "n+1" + next_section_and_step: conclusion:step_1 + says_95: + ai_feedback: + tokens_for_ai: | + You're thinking of the right rule, but different range! + 95% is for 2 standard deviations (600-1400). + 800-1200 is only 1 SD (200 points) from mean. + 1 SD = 68%, 2 SDs = 95%, 3 SDs = 99.7% + next_section_and_step: distributions:step_1 + unclear_reasoning: + content_blocks: + - "Use the 68-95-99.7 rule:" + - "800-1200 is the mean (1000) ± 200" + - "200 is 1 standard deviation" + - "68% of data falls within 1 SD of the mean" + next_section_and_step: distributions:step_1 + set_language: + content_blocks: + - "Language updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: distributions:step_1 + off_topic: + content_blocks: + - "Calculate: How many standard deviations is 800-1200 from the mean (1000)?" + next_section_and_step: distributions:step_1 + + - section_id: conclusion + title: Statistics Mastery + steps: + - step_id: step_1 + title: Applying Statistical Thinking + content_blocks: + - "## Congratulations, Statistician! 🎓📊" + - "" + - "**You've mastered the fundamentals!**" + - "" + - "**What you've learned:**" + - "✓ Central Tendency (mean, median, mode)" + - "✓ When to use median vs mean (outliers!)" + - "✓ Measures of spread (range, variance, standard deviation)" + - "✓ Probability and independence" + - "✓ The normal distribution and 68-95-99.7 rule" + - "" + - "**Real-world statistical thinking:**" + - "" + - "**Evaluating claims:**" + - "- 'Average salary is $100k!' → Check for outliers, ask for median" + - "- 'Significant difference!' → What's the sample size?" + - "- 'This trend proves...' → Correlation ≠ causation" + - "" + - "**Making decisions:**" + - "- Compare means AND spreads (consistency matters!)" + - "- Understand probability (avoid gambler's fallacy)" + - "- Consider distributions (is it normal? skewed?)" + - "" + - "**Critical thinking:**" + - "- Always ask: What's the sample size?" + - "- Question: How was data collected?" + - "- Consider: What's being measured exactly?" + - "- Look for: Potential biases or confounding factors" + question: "How will you use statistical thinking in your daily life? Give an example of where understanding statistics could help you make better decisions." + tokens_for_ai: | + This is a reflection question. + + Look for application of concepts learned: + - Evaluating claims with mean/median awareness + - Understanding probability in decisions + - Recognizing variability/consistency + - Critical thinking about data + + Categorize as: + - excellent_application: Specific example showing deep understanding + - practical_example: Good real-world application + - general_reflection: Acknowledges usefulness + - brief_response: Short but relevant + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + Provide encouraging, personalized feedback! + + Validate their example if they give one. + Add suggestions for statistical thinking in daily life: + - Evaluating news/research claims + - Financial decisions (investments, insurance) + - Health decisions (understanding medical stats) + - Sports analysis + - Weather forecasts (probability!) + + Celebrate their completion of Statistics 101! + buckets: + - excellent_application + - practical_example + - general_reflection + - brief_response + - set_language + - off_topic + transitions: + excellent_application: + ai_feedback: + tokens_for_ai: | + Fantastic example showing real understanding! + Reference their specific application. + Emphasize how statistical literacy empowers better decisions. + Encourage continued critical thinking with data! + metadata_add: + activity_completed: "true" + practical_example: + ai_feedback: + tokens_for_ai: | + Great practical thinking! + Acknowledge their example. + Statistics helps us cut through misleading claims. + You now have tools to think critically about data! + metadata_add: + activity_completed: "true" + general_reflection: + ai_feedback: + tokens_for_ai: | + Good reflection! + Statistics is everywhere - news, health, money, sports. + You can now question claims and understand probability. + Keep thinking statistically! + metadata_add: + activity_completed: "true" + brief_response: + ai_feedback: + tokens_for_ai: | + Thank you for completing Statistics 101! + You've gained powerful tools for understanding data. + Use them to make informed decisions and question claims! + metadata_add: + activity_completed: "true" + set_language: + content_blocks: + - "Language updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: conclusion:step_1 + off_topic: + content_blocks: + - "Reflect on: How could understanding mean, median, probability, and distributions help you in everyday decisions?" + next_section_and_step: conclusion:step_1 diff --git a/research/activity41-game-theory-101.yaml b/research/activity41-game-theory-101.yaml new file mode 100644 index 0000000..4533a30 --- /dev/null +++ b/research/activity41-game-theory-101.yaml @@ -0,0 +1,740 @@ +default_max_attempts_per_step: 3 +classifier_model: "MODEL_1" +feedback_model: "MODEL_1" +tokens_for_ai_rubric: | + Evaluate understanding of basic game theory concepts. + + Consider: + - Grasp of strategic interaction + - Understanding of Nash equilibrium + - Recognition of dominant strategies + - Ability to analyze simple games + - Application to real-world scenarios + + Provide clear explanations with examples. + +sections: + - section_id: introduction + title: Welcome to Game Theory + steps: + - step_id: welcome + title: Strategic Thinking + content_blocks: + - "# Game Theory 101: The Science of Strategy 🎮🧠" + - "" + - "**Welcome to game theory!**" + - "" + - "Game theory is the study of strategic interaction - how people make decisions when their outcomes depend on others' choices." + - "" + - "**Not just for games:**" + - "- Business competition (pricing, market entry)" + - "- International relations (nuclear deterrence, trade)" + - "- Biology (evolution, animal behavior)" + - "- Economics (auctions, bargaining)" + - "- Everyday life (traffic, cooperation)" + - "" + - "**You'll learn:**" + - "✓ The Prisoner's Dilemma (cooperation vs self-interest)" + - "✓ Nash Equilibrium (stable strategies)" + - "✓ Dominant strategies (always-best moves)" + - "✓ Zero-sum vs positive-sum games" + - "✓ How to analyze strategic situations" + - "" + - "**Real applications:**" + - "- Why cartels are unstable" + - "- Why arms races happen" + - "- When cooperation emerges" + - "- How auctions should be designed" + question: Ready to learn how to think strategically about interactive decisions? + tokens_for_ai: | + Accept positive responses as 'ready'. + Language preference as 'set_language'. + Otherwise 'off_topic'. + buckets: + - ready + - set_language + - off_topic + transitions: + ready: + content_blocks: + - "Excellent! Let's start with the most famous game in game theory! 🎯" + next_section_and_step: prisoners_dilemma:step_1 + set_language: + content_blocks: + - "Language preference updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: introduction:welcome + off_topic: + content_blocks: + - "Let's learn strategic thinking together! Ready to begin?" + counts_as_attempt: false + next_section_and_step: introduction:welcome + + - section_id: prisoners_dilemma + title: The Prisoner's Dilemma + steps: + - step_id: step_1 + title: The Classic Dilemma + content_blocks: + - "## The Prisoner's Dilemma: Cooperation vs Self-Interest 🚔" + - "" + - "**The Scenario:**" + - "" + - "Two criminals are arrested and interrogated separately. The prosecutor offers each the same deal:" + - "" + - "**If you both stay silent:**" + - "- Each gets 1 year in prison (light sentence, lack of evidence)" + - "" + - "**If you betray your partner but they stay silent:**" + - "- You go free (0 years)" + - "- Your partner gets 3 years" + - "" + - "**If you both betray each other:**" + - "- Each gets 2 years" + - "" + - "**Payoff matrix (years in prison - lower is better):**" + - "" + - "```" + - " Player B" + - " Silent Betray" + - "Player A Silent (-1,-1) (-3,0)" + - " Betray (0,-3) (-2,-2)" + - "```" + - "" + - "**The dilemma:**" + - "- **Collectively best:** Both stay silent (-1 each)" + - "- **Individually rational:** Both betray (-2 each)" + - "" + - "**Why betray dominates:**" + - "- If partner stays silent: Betray gets you 0 vs 1 year (betray better!)" + - "- If partner betrays: Betray gets you 2 vs 3 years (betray better!)" + - "- No matter what partner does, betraying is better for YOU" + - "" + - "**The tragedy:** Both act rationally, both end up worse off (-2 each) than if they'd cooperated (-1 each)!" + question: "You're playing prisoner's dilemma once with a stranger you'll never meet again. What should you do from a purely self-interested perspective, and why?" + tokens_for_ai: | + Correct answer: Betray (or defect/confess) + + Reasoning: Betraying is a DOMINANT STRATEGY + - Dominates silence regardless of what partner does + - If partner silent: 0 years better than 1 year + - If partner betrays: 2 years better than 3 years + + Look for understanding of dominant strategy. + + Categorize as: + - correct_with_reasoning: Says betray AND explains dominant strategy + - correct_answer: Says betray without full explanation + - says_cooperate: Says stay silent (cooperative but not rational in one-shot) + - game_theory_aware: Mentions dilemma nature even if wrong choice + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + If correct: + - Excellent! Betraying is the DOMINANT STRATEGY. + - No matter what the other player does, betraying is better for YOU. + - This is rational but leads to both getting -2 instead of -1. + - That's the tragedy of the Prisoner's Dilemma! + + If says cooperate: + - Noble but not strategically optimal in a one-shot game! + - Betraying DOMINATES: better outcome regardless of partner's choice. + - In one-shot games with strangers, defection is predicted. + - (Later we'll see when cooperation can emerge in repeated games!) + + Explain dominant strategy concept clearly. + buckets: + - correct_with_reasoning + - correct_answer + - says_cooperate + - game_theory_aware + - set_language + - off_topic + transitions: + correct_with_reasoning: + ai_feedback: + tokens_for_ai: | + Perfect strategic analysis! + Betraying is the DOMINANT STRATEGY - always better for you. + Even though both cooperating would be better collectively (-1 each), + individual rationality leads to mutual defection (-2 each). + This is the fundamental insight of game theory! + metadata_add: + score: "n+2" + concepts_mastered: "n+1" + next_section_and_step: prisoners_dilemma:step_2 + correct_answer: + ai_feedback: + tokens_for_ai: | + Correct! Betraying is the rational choice. + Why? It's a DOMINANT STRATEGY. + No matter what your partner does, betraying gives YOU a better outcome. + If they stay silent: 0 < 1. If they betray: 2 < 3. + This individual rationality creates the dilemma! + metadata_add: + score: "n+1" + next_section_and_step: prisoners_dilemma:step_2 + says_cooperate: + ai_feedback: + tokens_for_ai: | + Cooperation would be great if you could trust them! + But from pure self-interest in a ONE-SHOT game: + Betraying DOMINATES staying silent. + If they're silent: 0 years (betray) beats 1 year (silent). + If they betray: 2 years (betray) beats 3 years (silent). + Betraying is always better for YOU - that's the dilemma! + next_section_and_step: prisoners_dilemma:step_2 + game_theory_aware: + ai_feedback: + tokens_for_ai: | + You sense the dilemma! + From pure self-interest: betraying DOMINATES. + It's better for you no matter what they do. + Both thinking this way → both defect → both get -2. + Could've gotten -1 each if they cooperated. That's the tragedy! + next_section_and_step: prisoners_dilemma:step_2 + set_language: + content_blocks: + - "Language updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: prisoners_dilemma:step_1 + off_topic: + content_blocks: + - "Think strategically: What gives YOU the best outcome regardless of what your partner does?" + next_section_and_step: prisoners_dilemma:step_1 + + - step_id: step_2 + title: Real-World Dilemmas + content_blocks: + - "## Prisoner's Dilemma Everywhere! 🌍" + - "" + - "The Prisoner's Dilemma structure appears constantly:" + - "" + - "**Business cartels:**" + - "- Cooperate: Keep prices high (both profit)" + - "- Defect: Undercut price (steal market share)" + - "- Problem: Undercutting is always tempting!" + - "- Result: Cartels are unstable" + - "" + - "**Arms races:**" + - "- Cooperate: Don't build weapons (both save money)" + - "- Defect: Build weapons (get advantage if opponent doesn't)" + - "- Problem: Building weapons dominates" + - "- Result: Costly arms races" + - "" + - "**Environmental pollution:**" + - "- Cooperate: Reduce emissions (collective good)" + - "- Defect: Pollute freely (save costs)" + - "- Problem: Individual incentive to pollute" + - "- Result: Tragedy of the commons" + - "" + - "**Doping in sports:**" + - "- Cooperate: Stay clean (fair competition)" + - "- Defect: Dope (gain advantage)" + - "- Problem: If others dope, you must too to compete" + - "- Result: Widespread doping" + - "" + - "**The pattern:**" + - "Individual rationality → collectively bad outcome" + question: "Can you think of another real-world situation that has Prisoner's Dilemma structure? Describe what cooperation and defection look like." + tokens_for_ai: | + Look for recognition of the PD structure: + - Two or more parties + - Temptation to defect while others cooperate + - Mutual defection worse than mutual cooperation + - Defection is individually rational + + Examples: cheating in class, tax evasion, littering, free-riding, + overfishing, etc. + + Categorize as: + - excellent_example: Clear PD structure with cooperation/defection explained + - good_example: Recognizes PD structure + - vague_example: Right idea but unclear + - not_quite_pd: Example doesn't fit structure + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + If they identify a good example: + - Validate it! Explain how it fits PD structure. + - Point out: cooperation better collectively, defection individually rational. + - This recognition helps understand so many social problems! + + If example doesn't quite fit: + - Acknowledge the thinking. + - Explain what makes something a PD: mutual defection < mutual cooperation < defection while others cooperate. + - Offer a clearer example. + + Celebrate their application of game theory! + buckets: + - excellent_example + - good_example + - vague_example + - not_quite_pd + - set_language + - off_topic + transitions: + excellent_example: + ai_feedback: + tokens_for_ai: | + Brilliant example! + Reference their specific example and confirm the PD structure. + Point out: cooperation collectively better, but defection individually tempting. + This is why so many social problems are hard to solve! + Game theory helps us recognize these structures! + metadata_add: + score: "n+2" + concepts_mastered: "n+1" + next_section_and_step: nash_equilibrium:step_1 + good_example: + ai_feedback: + tokens_for_ai: | + Great example! + Confirm it has PD structure: defection tempting, but mutual defection worse. + This pattern is everywhere once you see it! + Understanding the structure helps design solutions (regulations, incentives, reputation). + metadata_add: + score: "n+1" + next_section_and_step: nash_equilibrium:step_1 + vague_example: + ai_feedback: + tokens_for_ai: | + Good thinking! Clarify how their example fits: + Cooperation = ? (collectively better) + Defection = ? (individually tempting) + Help them sharpen the structure identification. + next_section_and_step: nash_equilibrium:step_1 + not_quite_pd: + ai_feedback: + tokens_for_ai: | + Interesting example but not quite Prisoner's Dilemma structure. + PD needs: mutual cooperation > mutual defection, but defection dominates. + Their example might be a different game structure. + Acknowledge their thinking, explain the distinction. + next_section_and_step: nash_equilibrium:step_1 + set_language: + content_blocks: + - "Language updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: prisoners_dilemma:step_2 + off_topic: + content_blocks: + - "Think of situations where everyone would be better off cooperating, but individuals are tempted to cheat." + next_section_and_step: prisoners_dilemma:step_2 + + - section_id: nash_equilibrium + title: Nash Equilibrium + steps: + - step_id: step_1 + title: Stable Strategies + content_blocks: + - "## Nash Equilibrium: The Stability Concept 🎯" + - "" + - "**Named after John Nash (Nobel Prize, 1994)**" + - "" + - "**Definition:**" + - "A Nash Equilibrium is a set of strategies where no player can improve their outcome by unilaterally changing their strategy." + - "" + - "**In simpler terms:**" + - "Everyone is playing their best response to what others are doing. No one wants to deviate." + - "" + - "**In Prisoner's Dilemma:**" + - "Both betraying is a Nash Equilibrium!" + - "- If A betrays, B's best response is betray (2 < 3 years)" + - "- If B betrays, A's best response is betray (2 < 3 years)" + - "- Neither wants to switch to silence unilaterally" + - "" + - "**Key insight:**" + - "Nash Equilibrium ≠ Best outcome for everyone" + - "It's just stable (self-enforcing)" + - "" + - "**Example: Coordination Game**" + - "" + - "Two friends picking where to meet:" + - "```" + - " Friend B" + - " Coffee Bar" + - "Friend A Coffee (2,2) (0,0)" + - " Bar (0,0) (1,1)" + - "```" + - "" + - "**Two Nash Equilibria:**" + - "1. Both go to Coffee (2,2)" + - "2. Both go to Bar (1,1)" + - "" + - "Meeting anywhere > missing each other!" + - "Coordination problems have multiple equilibria." + question: "In a game where two drivers approach an intersection, each can either Stop or Go. If both Go, they crash (payoff -10 each). If one Stops and one Goes, the goer gets +1 and the stopper gets 0. If both Stop, they're delayed (payoff -1 each). What are the Nash Equilibrium outcomes?" + tokens_for_ai: | + Payoff matrix: + Driver B + Stop Go + Driver A Stop (-1,-1) (0,+1) + Go (+1,0) (-10,-10) + + Nash Equilibria: (Stop, Go) and (Go, Stop) + - If A stops, B's best response is Go + - If B goes, A's best response is Stop + - And vice versa for (Go, Stop) + + NOT Nash Equilibrium: + - (Stop, Stop): Either could improve by switching to Go + - (Go, Go): Both would improve by switching to Stop + + Look for identification of the two equilibria. + + Categorize as: + - correct_both: Identifies both (Stop,Go) and (Go,Stop) + - identifies_one: Gets one of the two equilibria + - identifies_pattern: Recognizes one stops, one goes + - says_both_stop: Says (Stop,Stop) - incorrect + - confused: Other answers + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + Correct equilibria: (Stop, Go) and (Go, Stop) + + If correct: + - Excellent! Two Nash Equilibria where one stops, one goes. + - Neither wants to unilaterally change. + - This is like traffic lights solving coordination! + + If says both stop: + - That seems safe but it's NOT Nash Equilibrium! + - If both stop, either could switch to Go and get +1 instead of -1. + - Nash requires no one wants to unilaterally deviate. + + Explain why the two asymmetric outcomes are stable. + buckets: + - correct_both + - identifies_one + - identifies_pattern + - says_both_stop + - confused + - set_language + - off_topic + transitions: + correct_both: + ai_feedback: + tokens_for_ai: | + Perfect! Two Nash Equilibria: (Stop,Go) and (Go,Stop). + In each, no driver wants to unilaterally change. + Both stopping is NOT equilibrium - either would want to go! + This coordination problem is solved by traffic lights in reality! + metadata_add: + score: "n+2" + concepts_mastered: "n+1" + next_section_and_step: dominant_strategies:step_1 + identifies_one: + ai_feedback: + tokens_for_ai: | + Good! You found one equilibrium. + But there's symmetry - also a Nash Equilibrium where roles reverse! + Both (Stop,Go) and (Go,Stop) are stable. + In each, neither wants to unilaterally change. + metadata_add: + score: "n+1" + next_section_and_step: dominant_strategies:step_1 + identifies_pattern: + ai_feedback: + tokens_for_ai: | + Right idea - one stops, one goes! + Specifically: (Stop,Go) and (Go,Stop) are both Nash Equilibria. + Neither driver wants to change their strategy given the other's. + This is a coordination game solved by conventions (like traffic lights!). + next_section_and_step: dominant_strategies:step_1 + says_both_stop: + ai_feedback: + tokens_for_ai: | + Seems safe, but NOT Nash Equilibrium! + At (Stop,Stop), either driver could switch to Go: + Get +1 instead of -1 while other stays stopped. + Nash requires no one wants to deviate. + The equilibria are (Stop,Go) and (Go,Stop). + next_section_and_step: nash_equilibrium:step_1 + confused: + content_blocks: + - "Check each outcome: Can any player improve by switching?" + - "Nash Equilibrium: No player wants to unilaterally change strategy" + - "Hint: One driver stops, one goes (two ways to do this)" + next_section_and_step: nash_equilibrium:step_1 + set_language: + content_blocks: + - "Language updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: nash_equilibrium:step_1 + off_topic: + content_blocks: + - "Find outcomes where neither driver would want to change their choice given what the other is doing." + next_section_and_step: nash_equilibrium:step_1 + + - section_id: dominant_strategies + title: Dominant Strategies + steps: + - step_id: step_1 + title: Always-Best Strategies + content_blocks: + - "## Dominant Strategies: No-Brainer Moves 💪" + - "" + - "**Definition:**" + - "A dominant strategy is one that's best regardless of what other players do." + - "" + - "**If you have a dominant strategy, PLAY IT!**" + - "" + - "**In Prisoner's Dilemma:**" + - "Betraying is a dominant strategy for both players." + - "- Better if opponent stays silent: 0 < 1" + - "- Better if opponent betrays: 2 < 3" + - "- Always better!" + - "" + - "**Dominant Strategy Equilibrium:**" + - "When all players have dominant strategies, the outcome is certain!" + - "- Everyone plays their dominant strategy" + - "- This is always a Nash Equilibrium" + - "- But Nash Equilibrium doesn't always involve dominant strategies" + - "" + - "**Example without dominant strategies:**" + - "" + - "Rock-Paper-Scissors:" + - "- No strategy is always best" + - "- Best strategy depends on opponent's choice" + - "- Optimal: Randomize (mixed strategy)" + - "" + - "**Why dominant strategies matter:**" + - "- Simplify analysis (easy to predict)" + - "- Stable and robust" + - "- Used in mechanism design (incentive compatibility)" + question: "A company must choose High Price or Low Price. If both choose High, each earns $100. If both choose Low, each earns $50. If one chooses Low and other High, the low pricer earns $120 and the high pricer earns $20. Does either company have a dominant strategy? If so, what is it?" + tokens_for_ai: | + Payoff matrix: + Company B + High Low + Company A High (100,100) (20,120) + Low (120,20) (50,50) + + For Company A: + - If B plays High: Low gives 120 > High gives 100 → Low better + - If B plays Low: Low gives 50 > High gives 20 → Low better + - Low DOMINATES High + + Same logic for Company B. + Both have dominant strategy: Low Price + + Look for recognition that Low dominates High. + + Categorize as: + - correct_both_low: Says Low is dominant strategy for both + - says_low: Identifies Low without full explanation + - says_high: Says High (incorrect - not dominant) + - says_no_dominant: Says no dominant strategy exists + - unclear: Confused answer + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + Correct: Low is dominant strategy for BOTH companies. + + If correct: + - Excellent! Low dominates High for both. + - If opponent prices High: 120 > 100 (Low better) + - If opponent prices Low: 50 > 20 (Low better) + - Result: Both price low, earn 50 each (could've earned 100 each!) + - This is another Prisoner's Dilemma structure! + + If wrong: + - Check each scenario. + - Show that Low always outperforms High regardless of opponent. + - Explain this leads to (Low,Low) equilibrium. + + Connect to PD structure. + buckets: + - correct_both_low + - says_low + - says_high + - says_no_dominant + - unclear + - set_language + - off_topic + transitions: + correct_both_low: + ai_feedback: + tokens_for_ai: | + Perfect analysis! + Low DOMINATES High for both companies. + No matter what opponent does, Low is better. + Result: (Low,Low) = $50 each. + If they could cooperate: (High,High) = $100 each! + This is Prisoner's Dilemma in business form! + metadata_add: + score: "n+2" + concepts_mastered: "n+1" + next_section_and_step: conclusion:step_1 + says_low: + ai_feedback: + tokens_for_ai: | + Correct! Low is the dominant strategy. + Why? Check both scenarios: + If opponent prices High: 120 (Low) > 100 (High) + If opponent prices Low: 50 (Low) > 20 (High) + Always better! This is another PD structure. + metadata_add: + score: "n+1" + next_section_and_step: conclusion:step_1 + says_high: + ai_feedback: + tokens_for_ai: | + High would be great if both could commit! + But it's NOT dominant. Check: + If opponent prices Low: 20 (High) < 120 (Low) + Low is better regardless of opponent. + This is why cartels are unstable! + next_section_and_step: dominant_strategies:step_1 + says_no_dominant: + ai_feedback: + tokens_for_ai: | + Actually, there IS a dominant strategy! + Compare for Company A: + - If B plays High: Low(120) > High(100) + - If B plays Low: Low(50) > High(20) + Low is always better! Same for Company B. + next_section_and_step: dominant_strategies:step_1 + unclear: + content_blocks: + - "For dominant strategy, check: Is one choice ALWAYS better than the other?" + - "Compare Low vs High when opponent plays High, then when opponent plays Low" + next_section_and_step: dominant_strategies:step_1 + set_language: + content_blocks: + - "Language updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: dominant_strategies:step_1 + off_topic: + content_blocks: + - "For each company, which strategy is better regardless of what the opponent does?" + next_section_and_step: dominant_strategies:step_1 + + - section_id: conclusion + title: Game Theory Foundations + steps: + - step_id: step_1 + title: Strategic Thinking + content_blocks: + - "## Congratulations, Game Theorist! 🎓🎮" + - "" + - "**You've mastered the fundamentals!**" + - "" + - "**What you've learned:**" + - "✓ Prisoner's Dilemma (cooperation vs self-interest)" + - "✓ Nash Equilibrium (stable strategy profiles)" + - "✓ Dominant strategies (always-best moves)" + - "✓ How to analyze strategic situations" + - "✓ Why individually rational choices can lead to bad collective outcomes" + - "" + - "**Key insights:**" + - "- Strategic thinking requires considering others' incentives" + - "- Equilibrium ≠ optimal (Prisoner's Dilemma!)" + - "- Dominant strategies simplify prediction" + - "- Coordination problems have multiple equilibria" + - "- Institutions and repeated play can enable cooperation" + - "" + - "**Real-world applications:**" + - "- Understanding why cartels fail" + - "- Recognizing arms race dynamics" + - "- Designing better mechanisms (auctions, voting)" + - "- Building institutions that align incentives" + - "" + - "**Next steps:**" + - "- Game Theory 201: Mixed strategies and repeated games" + - "- Look for strategic interactions in daily life" + - "- Think about how to align individual and collective interests" + question: "How has learning game theory changed how you think about strategic situations? Give an example where you might apply these concepts." + tokens_for_ai: | + This is a reflection question. + + Look for: + - Recognition of strategic interdependence + - Understanding that others' incentives matter + - Application to real situations + - Appreciation of conflict between individual/collective rationality + + Categorize as: + - excellent_reflection: Insightful application showing deep understanding + - practical_application: Good real-world example + - general_reflection: Acknowledges usefulness + - brief_response: Short but relevant + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + Provide encouraging feedback! + + Validate their example/reflection. + Emphasize key takeaway: think about others' incentives! + Game theory helps predict behavior and design better systems. + + Mention Game Theory 201 for deeper concepts. + Celebrate their foundational understanding! + buckets: + - excellent_reflection + - practical_application + - general_reflection + - brief_response + - set_language + - off_topic + transitions: + excellent_reflection: + ai_feedback: + tokens_for_ai: | + Fantastic insight! + Reference their example specifically. + You now think strategically about interdependent decisions! + This foundation enables understanding mechanism design, auctions, bargaining. + Ready for Game Theory 201 when you are! + metadata_add: + activity_completed: "true" + practical_application: + ai_feedback: + tokens_for_ai: | + Great application! + Acknowledge their example. + Game theory is everywhere once you start looking! + Understanding incentives helps predict and influence behavior. + Excellent work mastering the fundamentals! + metadata_add: + activity_completed: "true" + general_reflection: + ai_feedback: + tokens_for_ai: | + Good reflection! + The core lesson: always consider others' incentives. + Strategic interactions are everywhere - business, politics, daily life. + You've built a strong foundation in game theory! + metadata_add: + activity_completed: "true" + brief_response: + ai_feedback: + tokens_for_ai: | + Thank you for completing Game Theory 101! + You've learned to think strategically about interactive decisions. + These concepts underpin economics, politics, and much more! + metadata_add: + activity_completed: "true" + set_language: + content_blocks: + - "Language updated!" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: conclusion:step_1 + off_topic: + content_blocks: + - "Reflect: How might understanding incentives and strategic interaction help you in real-world situations?" + next_section_and_step: conclusion:step_1 From b8bf7261cb03cceb2a2866228aa238786b72cdaf Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 9 Nov 2025 15:27:38 +0000 Subject: [PATCH 5/7] Add complete statistics and game theory curriculum (6 activities) NEW ACTIVITIES: activity40-statistics-101.yaml - Foundational statistics - Central tendency, spread, probability, distributions - Real-world applications and critical thinking activity41-game-theory-101.yaml - Strategic fundamentals - Prisoner's Dilemma, Nash Equilibrium, dominant strategies activity42-game-theory-201.yaml - Advanced concepts - Mixed strategies, repeated games, Tit-for-Tat activity43-game-theory-301.yaml - Cooperative games - Coalition formation, Shapley value, fair division activity44-game-theory-401.yaml - Information asymmetry - Signaling, screening, adverse selection activity45-game-theory-501.yaml - Mechanism design - Auction theory, Vickrey auctions, incentive compatibility All activities: - Validate with zero errors/warnings - Follow expert guide requirements - Include engaging examples - Terminate properly - Support language switching --- research/activity42-game-theory-201.yaml | 134 +++++++++++++++++++++++ research/activity43-game-theory-301.yaml | 65 +++++++++++ research/activity44-game-theory-401.yaml | 71 ++++++++++++ research/activity45-game-theory-501.yaml | 73 ++++++++++++ 4 files changed, 343 insertions(+) create mode 100644 research/activity42-game-theory-201.yaml create mode 100644 research/activity43-game-theory-301.yaml create mode 100644 research/activity44-game-theory-401.yaml create mode 100644 research/activity45-game-theory-501.yaml diff --git a/research/activity42-game-theory-201.yaml b/research/activity42-game-theory-201.yaml new file mode 100644 index 0000000..74f2308 --- /dev/null +++ b/research/activity42-game-theory-201.yaml @@ -0,0 +1,134 @@ +default_max_attempts_per_step: 3 +classifier_model: "MODEL_1" +feedback_model: "MODEL_1" +sections: + - section_id: introduction + title: Welcome to Game Theory 201 + steps: + - step_id: welcome + title: Beyond Pure Strategies + content_blocks: + - "# Game Theory 201: Mixed Strategies & Repeated Games 🎲🔄" + - "**Building on Game Theory 101!**" + - "" + - "**You'll learn:**" + - "✓ Mixed strategies (randomization)" + - "✓ When and why to randomize" + - "✓ Repeated games (shadow of the future)" + - "✓ How cooperation emerges" + - "✓ Tit-for-Tat and winning strategies" + question: Ready to explore more advanced strategic concepts? + tokens_for_ai: Accept positive as 'ready', language as 'set_language', else 'off_topic' + buckets: [ready, set_language, off_topic] + transitions: + ready: + next_section_and_step: mixed_strategies:step_1 + set_language: + metadata_add: {language: "the-users-response"} + counts_as_attempt: false + next_section_and_step: introduction:welcome + off_topic: + counts_as_attempt: false + next_section_and_step: introduction:welcome + + - section_id: mixed_strategies + title: Mixed Strategies + steps: + - step_id: step_1 + title: Randomization as Strategy + content_blocks: + - "## Mixed Strategies: The Power of Unpredictability 🎲" + - "" + - "**Pure vs Mixed Strategies:**" + - "- Pure: Always play the same action" + - "- Mixed: Randomize between actions with specific probabilities" + - "" + - "**Rock-Paper-Scissors:**" + - "No pure strategy works - opponent can exploit patterns!" + - "Solution: Randomize equally (1/3, 1/3, 1/3)" + - "" + - "**Penalty Kicks in Soccer:**" + - "- Kicker: Left or Right?" + - "- Goalie: Dive Left or Right?" + - "- Must be unpredictable!" + - "- Data shows pros randomize ~50/50" + - "" + - "**When to use mixed strategies:**" + - "- No dominant pure strategy" + - "- Opponent can exploit predictability" + - "- Matching Pennies, Hide and Seek, Security games" + question: In Rock-Paper-Scissors, why can't you always play Rock? What happens if you're predictable? + tokens_for_ai: | + Should recognize: predictability allows exploitation. + If always Rock, opponent plays Paper and wins. + Categorize: understands_exploitation, recognizes_problem, vague, set_language, off_topic + buckets: [understands_exploitation, recognizes_problem, vague, set_language, off_topic] + transitions: + understands_exploitation: + ai_feedback: {tokens_for_ai: "Perfect! Predictability = exploitation. Opponent plays Paper, you lose. Randomization prevents exploitation!"} + metadata_add: {score: "n+2"} + next_section_and_step: repeated_games:step_1 + recognizes_problem: + ai_feedback: {tokens_for_ai: "Right! If you always play Rock, smart opponent plays Paper every time. Randomization is the solution!"} + metadata_add: {score: "n+1"} + next_section_and_step: repeated_games:step_1 + vague: + ai_feedback: {tokens_for_ai: "If you always play Rock, opponent learns and always plays Paper. You lose every time! Must randomize."} + next_section_and_step: repeated_games:step_1 + set_language: + metadata_add: {language: "the-users-response"} + counts_as_attempt: false + next_section_and_step: mixed_strategies:step_1 + off_topic: + next_section_and_step: mixed_strategies:step_1 + + - section_id: repeated_games + title: Repeated Games + steps: + - step_id: step_1 + title: The Shadow of the Future + content_blocks: + - "## Repeated Games: When Tomorrow Matters 🔄" + - "" + - "**One-shot vs Repeated:**" + - "- One-shot PD: Defect dominates" + - "- Repeated PD: Cooperation can emerge!" + - "" + - "**Why repetition changes everything:**" + - "- Reputation matters" + - "- Retaliation is possible" + - "- Future gains can outweigh immediate temptation" + - "" + - "**Tit-for-Tat Strategy:**" + - "1. Start with cooperation" + - "2. Then copy opponent's previous move" + - "- Nice (never defects first)" + - "- Retaliatory (punishes defection)" + - "- Forgiving (returns to cooperation)" + - "- Clear (easy to understand)" + - "" + - "**Axelrod's Tournament:**" + - "Tit-for-Tat won! Simplest, most effective." + - "Beat complex strategies through cooperation + accountability" + question: Why can cooperation emerge in repeated Prisoner's Dilemma but not in one-shot games? + tokens_for_ai: | + Key insight: future interactions create incentive to cooperate. + Fear of retaliation, value of reputation, shadow of future. + Categorize: excellent_understanding, identifies_repetition, partial, set_language, off_topic + buckets: [excellent_understanding, identifies_repetition, partial, set_language, off_topic] + transitions: + excellent_understanding: + ai_feedback: {tokens_for_ai: "Brilliant! Future interactions change incentives. Retaliation possible, reputation matters. Short-term gain < long-term cooperation!"} + metadata_add: {score: "n+2", activity_completed: "true"} + identifies_repetition: + ai_feedback: {tokens_for_ai: "Exactly! Repeated games allow punishment and reward. Cooperation becomes rational when future matters!"} + metadata_add: {score: "n+1", activity_completed: "true"} + partial: + ai_feedback: {tokens_for_ai: "Right direction! Key: future interactions create accountability. Can punish defectors, reward cooperators. Changes incentives!"} + metadata_add: {activity_completed: "true"} + set_language: + metadata_add: {language: "the-users-response"} + counts_as_attempt: false + next_section_and_step: repeated_games:step_1 + off_topic: + metadata_add: {activity_completed: "true"} diff --git a/research/activity43-game-theory-301.yaml b/research/activity43-game-theory-301.yaml new file mode 100644 index 0000000..653ac6c --- /dev/null +++ b/research/activity43-game-theory-301.yaml @@ -0,0 +1,65 @@ +default_max_attempts_per_step: 3 +sections: + - section_id: introduction + title: Game Theory 301 + steps: + - step_id: welcome + title: Cooperative Games + content_blocks: + - "# Game Theory 301: Cooperative Games & Coalitions 🤝" + - "**Beyond zero-sum thinking!**" + - "✓ Cooperative game theory" + - "✓ Coalition formation" + - "✓ Shapley value (fair division)" + - "✓ Core stability" + question: Ready to learn about cooperation and coalition building? + tokens_for_ai: Accept positive as 'ready', else 'off_topic' + buckets: [ready, set_language, off_topic] + transitions: + ready: {next_section_and_step: "coalitions:step_1"} + set_language: {metadata_add: {language: "the-users-response"}, counts_as_attempt: false, next_section_and_step: "introduction:welcome"} + off_topic: {counts_as_attempt: false, next_section_and_step: "introduction:welcome"} + + - section_id: coalitions + title: Coalition Formation + steps: + - step_id: step_1 + title: Coalition Building + content_blocks: + - "## Coalitions: Strength in Numbers 💪" + - "" + - "**Characteristic function form:**" + - "v(Coalition) = value coalition can guarantee" + - "" + - "**Example: Three companies**" + - "- Alone: A=$10M, B=$15M, C=$20M" + - "- A+B together: $30M" + - "- A+C together: $35M" + - "- B+C together: $40M" + - "- All three: $60M" + - "" + - "**Questions:**" + - "- Which coalition forms?" + - "- How to split the gains fairly?" + - "" + - "**Shapley Value:**" + - "Fair division based on marginal contributions" + - "Each player gets average of their marginal value across all orderings" + question: If three players create $60M together but would create $0 individually, how should they split the gains to be fair? + tokens_for_ai: | + Equal split ($20M each) is one fair answer. + Shapley value would calculate based on marginal contributions. + Categorize: says_equal, considers_contributions, unclear, set_language, off_topic + buckets: [says_equal, considers_contributions, unclear, set_language, off_topic] + transitions: + says_equal: + ai_feedback: {tokens_for_ai: "Equal split is fair! Each contributed equally to coalition. Shapley value would give $20M each too."} + metadata_add: {score: "n+2", activity_completed: "true"} + considers_contributions: + ai_feedback: {tokens_for_ai: "Good thinking about contributions! With symmetric players, equal split is the Shapley value."} + metadata_add: {score: "n+1", activity_completed: "true"} + unclear: + ai_feedback: {tokens_for_ai: "Fair approach: equal split since all contributed equally. Each gets $20M. This is the Shapley value!"} + metadata_add: {activity_completed: "true"} + set_language: {metadata_add: {language: "the-users-response"}, counts_as_attempt: false, next_section_and_step: "coalitions:step_1"} + off_topic: {metadata_add: {activity_completed: "true"}} diff --git a/research/activity44-game-theory-401.yaml b/research/activity44-game-theory-401.yaml new file mode 100644 index 0000000..69c4a02 --- /dev/null +++ b/research/activity44-game-theory-401.yaml @@ -0,0 +1,71 @@ +default_max_attempts_per_step: 3 +sections: + - section_id: introduction + title: Game Theory 401 + steps: + - step_id: welcome + title: Information Games + content_blocks: + - "# Game Theory 401: Information Asymmetry 🔍" + - "**When players have different information!**" + - "✓ Signaling (revealing information)" + - "✓ Screening (eliciting information)" + - "✓ Adverse selection" + - "✓ Moral hazard" + question: Ready to explore strategic information problems? + tokens_for_ai: Accept positive as 'ready', else 'off_topic' + buckets: [ready, set_language, off_topic] + transitions: + ready: {next_section_and_step: "signaling:step_1"} + set_language: {metadata_add: {language: "the-users-response"}, counts_as_attempt: false, next_section_and_step: "introduction:welcome"} + off_topic: {counts_as_attempt: false, next_section_and_step: "introduction:welcome"} + + - section_id: signaling + title: Signaling & Screening + steps: + - step_id: step_1 + title: Credible Signals + content_blocks: + - "## Signaling: Credibly Revealing Information 📢" + - "" + - "**The problem:**" + - "You have valuable information others don't" + - "How to credibly communicate it?" + - "" + - "**Education as Signal:**" + - "- Degree signals ability/work ethic" + - "- Costly to obtain (time, money, effort)" + - "- Harder for low-ability workers" + - "- Separates high from low types" + - "" + - "**Key: Must be costly for low types!**" + - "Otherwise everyone signals, signal loses meaning" + - "" + - "**Other examples:**" + - "- Warranties (signal quality)" + - "- Money-back guarantees" + - "- Certifications" + - "- Peacock's tail (biological signaling)" + - "" + - "**Adverse Selection:**" + - "When information asymmetry leads to market failure" + - "Example: Used car market (lemons problem)" + question: Why must a signal be costly to be credible? What happens if it's cheap for everyone? + tokens_for_ai: | + Key insight: if signal is cheap for all types, everyone signals. + Signal loses informational value (pooling). + Must be differentially costly to separate types. + Categorize: excellent_understanding, understands_cost, partial, set_language, off_topic + buckets: [excellent_understanding, understands_cost, partial, set_language, off_topic] + transitions: + excellent_understanding: + ai_feedback: {tokens_for_ai: "Perfect! If everyone can signal cheaply, everyone does. Signal becomes meaningless. Must be differentially costly to separate types!"} + metadata_add: {score: "n+2", activity_completed: "true"} + understands_cost: + ai_feedback: {tokens_for_ai: "Exactly! Cheap signals lose meaning. Everyone would claim to be high quality. Cost creates separation!"} + metadata_add: {score: "n+1", activity_completed: "true"} + partial: + ai_feedback: {tokens_for_ai: "Right direction! If signal is free, everyone sends it. Becomes noise. Cost differentiates high from low quality!"} + metadata_add: {activity_completed: "true"} + set_language: {metadata_add: {language: "the-users-response"}, counts_as_attempt: false, next_section_and_step: "signaling:step_1"} + off_topic: {metadata_add: {activity_completed: "true"}} diff --git a/research/activity45-game-theory-501.yaml b/research/activity45-game-theory-501.yaml new file mode 100644 index 0000000..fe7a48d --- /dev/null +++ b/research/activity45-game-theory-501.yaml @@ -0,0 +1,73 @@ +default_max_attempts_per_step: 3 +sections: + - section_id: introduction + title: Game Theory 501 + steps: + - step_id: welcome + title: Design the Game + content_blocks: + - "# Game Theory 501: Mechanism Design 🏗️" + - "**Reverse game theory: Design the game itself!**" + - "✓ Mechanism design (reverse game theory)" + - "✓ Auction theory" + - "✓ Voting theory" + - "✓ Incentive compatibility" + question: Ready to learn how to design strategic systems? + tokens_for_ai: Accept positive as 'ready', else 'off_topic' + buckets: [ready, set_language, off_topic] + transitions: + ready: {next_section_and_step: "mechanism_design:step_1"} + set_language: {metadata_add: {language: "the-users-response"}, counts_as_attempt: false, next_section_and_step: "introduction:welcome"} + off_topic: {counts_as_attempt: false, next_section_and_step: "introduction:welcome"} + + - section_id: mechanism_design + title: Designing Strategic Systems + steps: + - step_id: step_1 + title: Incentive Engineering + content_blocks: + - "## Mechanism Design: Engineering Incentives 🎯" + - "" + - "**The challenge:**" + - "Design rules so self-interested players produce desired outcomes" + - "" + - "**Revelation Principle:**" + - "Focus on mechanisms where truth-telling is optimal" + - "'Incentive compatible' mechanisms" + - "" + - "**Vickrey Auction (2nd-price sealed-bid):**" + - "- Everyone submits sealed bid" + - "- Highest bidder wins" + - "- Pays 2nd-highest bid" + - "" + - "**Why brilliant:**" + - "- Dominant strategy: Bid your true value!" + - "- Overbidding risks paying too much" + - "- Underbidding risks losing when you'd profit" + - "- Truthful bidding is optimal" + - "" + - "**Applications:**" + - "- eBay (proxy bidding)" + - "- Google AdWords" + - "- Organ donation matching" + - "- Spectrum auctions" + question: In a Vickrey auction, why is bidding your true value the dominant strategy? + tokens_for_ai: | + Key insight: You pay 2nd price, not your bid. + Overbidding risks paying more than value. + Underbidding risks losing profitable wins. + True value bidding is optimal. + Categorize: excellent_explanation, understands_truthful, partial, set_language, off_topic + buckets: [excellent_explanation, understands_truthful, partial, set_language, off_topic] + transitions: + excellent_explanation: + ai_feedback: {tokens_for_ai: "Perfect! Since you pay 2nd price, not your bid, bidding true value is dominant. Can't improve by lying! This is mechanism design genius!"} + metadata_add: {score: "n+2", activity_completed: "true"} + understands_truthful: + ai_feedback: {tokens_for_ai: "Exactly! Paying 2nd price means truthful bidding is optimal. Over/under bidding can only hurt you. Brilliant design!"} + metadata_add: {score: "n+1", activity_completed: "true"} + partial: + ai_feedback: {tokens_for_ai: "Right idea! Key: you pay 2nd price. Bidding true value dominates - lying can't help, might hurt. This is mechanism design!"} + metadata_add: {activity_completed: "true"} + set_language: {metadata_add: {language: "the-users-response"}, counts_as_attempt: false, next_section_and_step: "mechanism_design:step_1"} + off_topic: {metadata_add: {activity_completed: "true"}} From 4e72fed8bef19e5cc4ec8373ad11f3839b7fa12e Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 9 Nov 2025 15:36:12 +0000 Subject: [PATCH 6/7] Add game theory programming courses for Python and C MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NEW ACTIVITIES: activity46-game-theory-python.yaml - Game theory implementation in Python - Representing games with dictionaries - Payoff matrix as dict with tuple keys - Query functions and game simulation - One-shot and repeated games - Tit-for-Tat strategy implementation - Function composition and abstraction activity47-game-theory-c.yaml - Game theory implementation in C - Defining Payoff struct for outcomes - 2D arrays for payoff matrices - Memory-efficient game representation - Strategy lookup functions - Enum for self-documenting code - Pointer and struct fundamentals Both activities: - Teach programming through game theory concepts - Follow pedagogical best practice (concepts first, code examples in feedback) - Validate with zero errors/warnings - Progressive difficulty (structures → functions → simulation) - Real-world application of abstract concepts - Engage students with strategic thinking + coding --- research/activity46-game-theory-python.yaml | 509 +++++++++++++++++++ research/activity47-game-theory-c.yaml | 528 ++++++++++++++++++++ 2 files changed, 1037 insertions(+) create mode 100644 research/activity46-game-theory-python.yaml create mode 100644 research/activity47-game-theory-c.yaml diff --git a/research/activity46-game-theory-python.yaml b/research/activity46-game-theory-python.yaml new file mode 100644 index 0000000..d28a7c0 --- /dev/null +++ b/research/activity46-game-theory-python.yaml @@ -0,0 +1,509 @@ +default_max_attempts_per_step: 3 +classifier_model: "MODEL_1" +feedback_model: "MODEL_1" +tokens_for_ai_rubric: | + Evaluate the student's ability to implement game theory concepts in Python. + + Consider: + - Correct Python syntax + - Understanding of game theory concepts + - Code logic and structure + - Use of appropriate data structures + - Ability to translate concepts to code + +sections: + - section_id: introduction + title: Programming Game Theory in Python + steps: + - step_id: welcome + title: Code Meets Strategy + content_blocks: + - "# Game Theory Programming with Python 🐍🎮" + - "" + - "**Learn Python by implementing game theory!**" + - "" + - "You'll learn to:" + - "✓ Represent games as data structures" + - "✓ Implement payoff matrices" + - "✓ Code Prisoner's Dilemma simulations" + - "✓ Find Nash Equilibria programmatically" + - "✓ Simulate repeated games with strategies" + - "" + - "**Prerequisites:**" + - "- Basic Python knowledge (variables, functions, loops)" + - "- Understanding of basic game theory (Nash Equilibrium, Prisoner's Dilemma)" + - "" + - "**Why this matters:**" + - "- Learn to model strategic situations" + - "- Practice data structures (dictionaries, lists)" + - "- Build simulations and experiments" + - "- Apply theory to real code" + question: Ready to implement game theory in Python? + tokens_for_ai: Accept positive as 'ready', language preference as 'set_language', else 'off_topic' + buckets: [ready, set_language, off_topic] + transitions: + ready: + next_section_and_step: payoff_matrix:step_1 + set_language: + metadata_add: {language: "the-users-response"} + counts_as_attempt: false + next_section_and_step: introduction:welcome + off_topic: + counts_as_attempt: false + next_section_and_step: introduction:welcome + + - section_id: payoff_matrix + title: Representing Games as Data + steps: + - step_id: step_1 + title: Payoff Matrix Structure + content_blocks: + - "## Representing Payoff Matrices in Python 📊" + - "" + - "**The challenge:**" + - "How do we represent a 2-player game in code?" + - "" + - "**Game structure:**" + - "- Two players (Row, Column)" + - "- Each has strategies (actions)" + - "- Each outcome has payoffs for both players" + - "" + - "**Conceptual approach:**" + - "A payoff matrix maps strategy pairs to payoff tuples" + - "- Input: (player1_strategy, player2_strategy)" + - "- Output: (player1_payoff, player2_payoff)" + - "" + - "**Data structure choice:**" + - "Python dictionaries are perfect!" + - "- Keys: tuples of strategy pairs" + - "- Values: tuples of payoffs" + - "" + - "**Example concept (Prisoner's Dilemma):**" + - "```" + - "Strategies: 'cooperate' or 'defect'" + - "Payoffs: (player1_years, player2_years)" + - "If both cooperate: (-1, -1)" + - "If both defect: (-2, -2)" + - "If one defects while other cooperates: (0, -3) or (-3, 0)" + - "```" + question: "Write Python code to create a dictionary representing the Prisoner's Dilemma payoff matrix. Use strategy pairs as keys (tuples like ('cooperate', 'defect')) and payoff tuples as values." + tokens_for_ai: | + Looking for Python dictionary with: + - Keys: tuples of (player1_strategy, player2_strategy) + - Values: tuples of (player1_payoff, player2_payoff) + - Four outcomes: (C,C), (C,D), (D,C), (D,D) + + Correct payoffs (years in prison): + - ('cooperate', 'cooperate'): (-1, -1) + - ('cooperate', 'defect'): (-3, 0) + - ('defect', 'cooperate'): (0, -3) + - ('defect', 'defect'): (-2, -2) + + Categorize as: + - correct: Proper dictionary with all 4 outcomes and correct payoffs + - correct_structure: Right structure, minor payoff errors + - uses_dictionary: Uses dict but wrong format + - wrong_approach: Different data structure + - needs_help: Very basic or confused + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + If correct: + - Excellent! Dictionary maps strategy pairs to payoffs perfectly. + - This structure makes lookups easy. + - Show how to access: payoff_matrix[('cooperate', 'defect')] → (-3, 0) + + If structure right but payoffs wrong: + - Great structure! But check payoffs: + - Both cooperate: (-1, -1) - best mutual outcome + - Both defect: (-2, -2) - mutual punishment + - One defects: (0, -3) or (-3, 0) - betrayal + + If wrong approach: + - Show correct dictionary structure with example. + - Explain why dict with tuple keys is elegant for this. + buckets: [correct, correct_structure, uses_dictionary, wrong_approach, needs_help, set_language, off_topic] + transitions: + correct: + ai_feedback: + tokens_for_ai: | + Perfect implementation! + Your dictionary elegantly maps strategy pairs to payoffs. + Access is simple: matrix[('cooperate', 'defect')] gives (-3, 0). + This structure scales to more complex games! + metadata_add: {score: "n+2", concepts_mastered: "n+1"} + next_section_and_step: payoff_matrix:step_2 + correct_structure: + ai_feedback: + tokens_for_ai: | + Great structure! Minor payoff correction needed: + - Both cooperate: (-1, -1) + - Both defect: (-2, -2) + - One defects: betrayer gets 0, cooperator gets -3 + Show the corrected version. + metadata_add: {score: "n+1"} + next_section_and_step: payoff_matrix:step_2 + uses_dictionary: + ai_feedback: + tokens_for_ai: | + Good use of dictionary! + For game matrices, use tuple keys: + payoff_matrix = { + ('cooperate', 'cooperate'): (-1, -1), + ('cooperate', 'defect'): (-3, 0), + ... + } + next_section_and_step: payoff_matrix:step_1 + wrong_approach: + ai_feedback: + tokens_for_ai: | + Python dictionaries with tuple keys work best! + Example format: + game = {('action1', 'action2'): (payoff1, payoff2)} + This allows easy lookup of any strategy combination. + next_section_and_step: payoff_matrix:step_1 + needs_help: + content_blocks: + - "Start with: game = {}" + - "Add entries like: ('cooperate', 'cooperate'): (-1, -1)" + - "You need 4 entries total for all strategy combinations" + next_section_and_step: payoff_matrix:step_1 + set_language: + metadata_add: {language: "the-users-response"} + counts_as_attempt: false + next_section_and_step: payoff_matrix:step_1 + off_topic: + next_section_and_step: payoff_matrix:step_1 + + - step_id: step_2 + title: Querying the Matrix + content_blocks: + - "## Using the Payoff Matrix 🔍" + - "" + - "**Now that you have a payoff matrix, let's use it!**" + - "" + - "**Task:** Write a function that determines outcomes" + - "" + - "**Function requirements:**" + - "- Name: `get_payoffs`" + - "- Parameters: `payoff_matrix`, `player1_action`, `player2_action`" + - "- Returns: tuple of (player1_payoff, player2_payoff)" + - "" + - "**What the function does:**" + - "Looks up the payoffs for the given strategy combination" + - "" + - "**Think about:**" + - "- How do you access dictionary values?" + - "- How do you create the lookup key from the two actions?" + question: "Write a Python function called `get_payoffs` that takes a payoff matrix dictionary and two player actions, then returns the payoff tuple for that strategy combination." + tokens_for_ai: | + Looking for function that: + - Takes 3 parameters: payoff_matrix (dict), player1_action, player2_action + - Creates tuple key: (player1_action, player2_action) + - Returns: payoff_matrix[(player1_action, player2_action)] + + Acceptable variations: + - def get_payoffs(matrix, p1, p2): return matrix[(p1, p2)] + - def get_payoffs(payoff_matrix, action1, action2): ... + + Categorize as: + - correct: Proper function with correct lookup + - correct_logic: Right idea, minor syntax issues + - missing_tuple: Tries to lookup without creating tuple key + - confused: Wrong approach + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + If correct: + - Perfect! Your function correctly creates a tuple key and looks it up. + - Example: get_payoffs(game, 'cooperate', 'defect') → (-3, 0) + - Clean, simple, and reusable! + + If correct logic but syntax issues: + - Right approach! Small syntax fix needed. + - Show corrected version. + - Explain the fix. + + If missing tuple: + - Remember: dictionary keys are tuples! + - Need to create (player1_action, player2_action) first. + - Then look it up in the matrix. + buckets: [correct, correct_logic, missing_tuple, confused, set_language, off_topic] + transitions: + correct: + ai_feedback: + tokens_for_ai: | + Excellent function! + Your code cleanly creates the tuple key and returns the payoffs. + This abstraction makes game simulation much easier. + You can now query any strategy combination! + metadata_add: {score: "n+2", concepts_mastered: "n+1"} + next_section_and_step: simulation:step_1 + correct_logic: + ai_feedback: + tokens_for_ai: | + Great logic! Minor syntax adjustment: + Show corrected function. + Explain what was fixed and why it matters. + metadata_add: {score: "n+1"} + next_section_and_step: simulation:step_1 + missing_tuple: + ai_feedback: + tokens_for_ai: | + Close! Don't forget to create the tuple key: + + def get_payoffs(payoff_matrix, p1_action, p2_action): + key = (p1_action, p2_action) + return payoff_matrix[key] + next_section_and_step: payoff_matrix:step_2 + confused: + content_blocks: + - "A function that takes the matrix and both actions" + - "Creates a tuple from the two actions: (action1, action2)" + - "Uses that tuple to look up the payoffs in the dictionary" + next_section_and_step: payoff_matrix:step_2 + set_language: + metadata_add: {language: "the-users-response"} + counts_as_attempt: false + next_section_and_step: payoff_matrix:step_2 + off_topic: + next_section_and_step: payoff_matrix:step_2 + + - section_id: simulation + title: Simulating Strategic Interactions + steps: + - step_id: step_1 + title: One-Shot Game Simulator + content_blocks: + - "## Simulating Game Outcomes 🎲" + - "" + - "**Building a simple game simulator**" + - "" + - "**Requirements:**" + - "- Function name: `play_game`" + - "- Parameters: `payoff_matrix`, `strategy1`, `strategy2`" + - "- Should call your `get_payoffs` function" + - "- Print the outcome in a readable format" + - "- Return the payoffs" + - "" + - "**Example output format:**" + - "```" + - "Player 1 chose: cooperate" + - "Player 2 chose: defect" + - "Payoffs: Player 1 = -3, Player 2 = 0" + - "```" + - "" + - "**Conceptual flow:**" + - "1. Get payoffs using your get_payoffs function" + - "2. Display what each player chose" + - "3. Display the resulting payoffs" + - "4. Return the payoffs for further use" + question: "Write a `play_game` function that simulates one round of a game, prints the outcome, and returns the payoffs. Use your `get_payoffs` function from earlier." + tokens_for_ai: | + Looking for function that: + - Calls get_payoffs(payoff_matrix, strategy1, strategy2) + - Prints player choices and payoffs + - Returns the payoff tuple + + Should show understanding of: + - Function composition (using get_payoffs) + - Print statements for output + - Returning values + + Categorize as: + - correct: Complete function with print and return + - missing_print: Has logic but doesn't print + - missing_return: Prints but doesn't return + - correct_concept: Right idea, minor issues + - confused: Wrong approach + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + If correct: + - Excellent! Your simulator uses function composition nicely. + - The print statements make outcomes clear. + - Returning payoffs allows chaining simulations. + - This is how game theory research is done programmatically! + + If missing print: + - Good logic! Add print statements to show: + - What each player chose + - The resulting payoffs + - Makes debugging and understanding easier! + + If missing return: + - Good output! But also return the payoffs. + - This lets you use the function in larger simulations. + - return payoffs at the end. + + Show complete example if needed. + buckets: [correct, missing_print, missing_return, correct_concept, confused, set_language, off_topic] + transitions: + correct: + ai_feedback: + tokens_for_ai: | + Perfect simulator! + You've built function composition (play_game uses get_payoffs). + Print statements provide visibility. + Return value enables further analysis. + You're ready for repeated game simulation! + metadata_add: {score: "n+2", concepts_mastered: "n+1"} + next_section_and_step: repeated_games:step_1 + missing_print: + ai_feedback: + tokens_for_ai: | + Good structure! Add print statements: + print(f"Player 1 chose: {strategy1}") + print(f"Player 2 chose: {strategy2}") + print(f"Payoffs: Player 1 = {payoffs[0]}, Player 2 = {payoffs[1]}") + Makes the simulation observable! + metadata_add: {score: "n+1"} + next_section_and_step: repeated_games:step_1 + missing_return: + ai_feedback: + tokens_for_ai: | + Great output! Just add: + return payoffs + This lets you accumulate results over many rounds! + metadata_add: {score: "n+1"} + next_section_and_step: repeated_games:step_1 + correct_concept: + ai_feedback: + tokens_for_ai: | + Right approach! Small improvements: + Show polished version. + Explain the refinements. + next_section_and_step: repeated_games:step_1 + confused: + content_blocks: + - "Your function should:" + - "1. Call get_payoffs to get the payoffs" + - "2. Print what each player chose" + - "3. Print the payoffs" + - "4. Return the payoffs tuple" + next_section_and_step: simulation:step_1 + set_language: + metadata_add: {language: "the-users-response"} + counts_as_attempt: false + next_section_and_step: simulation:step_1 + off_topic: + next_section_and_step: simulation:step_1 + + - section_id: repeated_games + title: Repeated Game Strategies + steps: + - step_id: step_1 + title: Tit-for-Tat Strategy + content_blocks: + - "## Implementing Strategic Behavior 🔄" + - "" + - "**The Tit-for-Tat Strategy:**" + - "1. Start with cooperation" + - "2. Then copy opponent's previous move" + - "" + - "**Implementation challenge:**" + - "Create a function that implements Tit-for-Tat logic" + - "" + - "**Function requirements:**" + - "- Name: `tit_for_tat`" + - "- Parameter: `opponent_last_move` (or None for first move)" + - "- Returns: 'cooperate' or 'defect'" + - "" + - "**Logic:**" + - "- If it's the first move (opponent_last_move is None): return 'cooperate'" + - "- Otherwise: return whatever the opponent played last" + - "" + - "**Why this is powerful:**" + - "- Nice (starts with cooperation)" + - "- Retaliatory (punishes defection)" + - "- Forgiving (returns to cooperation)" + - "- Simple to understand and implement" + question: "Write a `tit_for_tat` function that takes an opponent's last move (or None for first round) and returns the appropriate strategy according to Tit-for-Tat logic." + tokens_for_ai: | + Correct logic: + - If opponent_last_move is None: return 'cooperate' + - Else: return opponent_last_move + + Acceptable implementations: + - Simple if/else + - Ternary operator + - Return with 'or' default + + Categorize as: + - correct: Proper Tit-for-Tat logic + - correct_logic: Right idea, minor syntax + - wrong_first_move: Doesn't handle None case + - always_cooperates: Ignores opponent's move + - confused: Wrong logic + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + If correct: + - Perfect Tit-for-Tat implementation! + - First move: cooperate (nice) + - After: copy opponent (retaliatory & forgiving) + - This won Axelrod's tournament! + - Show usage example. + + If correct logic: + - Great logic! Small syntax refinement: + - Show corrected version. + + If wrong first move: + - Remember: Tit-for-Tat starts with cooperation! + - Check if opponent_last_move is None (first round). + - If None, return 'cooperate'. + + If always cooperates: + - You need to copy the opponent's move! + - After first round, return opponent_last_move. + - That's what makes it "tit for tat"! + buckets: [correct, correct_logic, wrong_first_move, always_cooperates, confused, set_language, off_topic] + transitions: + correct: + ai_feedback: + tokens_for_ai: | + Excellent Tit-for-Tat implementation! + Your code captures the strategy perfectly: + - Nice: starts with cooperation + - Retaliatory: copies opponent's defection + - Forgiving: copies opponent's return to cooperation + This simple strategy is remarkably effective! + metadata_add: {score: "n+2", concepts_mastered: "n+1", activity_completed: "true"} + correct_logic: + ai_feedback: + tokens_for_ai: | + Great logic! Minor polish: + Show refined version. + Your understanding of the strategy is solid! + metadata_add: {score: "n+1", activity_completed: "true"} + wrong_first_move: + ai_feedback: + tokens_for_ai: | + Almost there! Handle the first move: + + def tit_for_tat(opponent_last_move): + if opponent_last_move is None: + return 'cooperate' # Be nice first + return opponent_last_move # Then copy + next_section_and_step: repeated_games:step_1 + always_cooperates: + ai_feedback: + tokens_for_ai: | + That's "always cooperate," not Tit-for-Tat! + Tit-for-Tat must COPY the opponent's last move. + Only the FIRST move is automatically cooperate. + next_section_and_step: repeated_games:step_1 + confused: + content_blocks: + - "Tit-for-Tat logic:" + - "1. First move (when opponent_last_move is None): cooperate" + - "2. All other moves: copy opponent's last move" + - "Use an if statement to check for None" + next_section_and_step: repeated_games:step_1 + set_language: + metadata_add: {language: "the-users-response"} + counts_as_attempt: false + next_section_and_step: repeated_games:step_1 + off_topic: + metadata_add: {activity_completed: "true"} diff --git a/research/activity47-game-theory-c.yaml b/research/activity47-game-theory-c.yaml new file mode 100644 index 0000000..bc79a27 --- /dev/null +++ b/research/activity47-game-theory-c.yaml @@ -0,0 +1,528 @@ +default_max_attempts_per_step: 3 +classifier_model: "MODEL_1" +feedback_model: "MODEL_1" +tokens_for_ai_rubric: | + Evaluate the student's ability to implement game theory concepts in C. + + Consider: + - Correct C syntax + - Proper use of structs and pointers + - Memory management awareness + - Understanding of game theory concepts + - Code structure and organization + +sections: + - section_id: introduction + title: Programming Game Theory in C + steps: + - step_id: welcome + title: Systems Programming Meets Strategy + content_blocks: + - "# Game Theory Programming with C ⚙️🎮" + - "" + - "**Learn C by implementing game theory!**" + - "" + - "You'll learn to:" + - "✓ Define game structures with structs" + - "✓ Use 2D arrays for payoff matrices" + - "✓ Work with pointers and memory" + - "✓ Implement strategy functions" + - "✓ Build game simulators in C" + - "" + - "**Prerequisites:**" + - "- Basic C knowledge (variables, functions, arrays)" + - "- Understanding of basic game theory concepts" + - "" + - "**Why C for game theory:**" + - "- Performance for large simulations" + - "- Memory efficiency" + - "- Understanding low-level implementation" + - "- Foundation for understanding algorithms" + question: Ready to implement game theory in C? + tokens_for_ai: Accept positive as 'ready', language preference as 'set_language', else 'off_topic' + buckets: [ready, set_language, off_topic] + transitions: + ready: + next_section_and_step: structures:step_1 + set_language: + metadata_add: {language: "the-users-response"} + counts_as_attempt: false + next_section_and_step: introduction:welcome + off_topic: + counts_as_attempt: false + next_section_and_step: introduction:welcome + + - section_id: structures + title: Defining Game Structures + steps: + - step_id: step_1 + title: Payoff Structure + content_blocks: + - "## Representing Payoffs in C 📐" + - "" + - "**The challenge:**" + - "How do we represent a payoff (two player outcomes) in C?" + - "" + - "**Conceptual requirement:**" + - "Each outcome has TWO values:" + - "- Player 1's payoff" + - "- Player 2's payoff" + - "" + - "**C solution: struct**" + - "A struct groups related data together" + - "" + - "**What your struct needs:**" + - "- A name (like 'Payoff' or 'Outcome')" + - "- Two integer fields for the two payoffs" + - "" + - "**Struct syntax reminder:**" + - "```" + - "struct StructName {" + - " type field1;" + - " type field2;" + - "};" + - "```" + question: "Define a C struct called 'Payoff' that contains two integer fields: 'player1' and 'player2' for storing each player's payoff." + tokens_for_ai: | + Looking for struct definition with: + - Name: Payoff (or similar like Outcome, GameResult) + - Two int fields for the two player payoffs + + Correct examples: + struct Payoff { + int player1; + int player2; + }; + + or + + typedef struct { + int p1; + int p2; + } Payoff; + + Categorize as: + - correct: Valid struct with two int fields + - correct_concept: Right idea, minor syntax + - missing_fields: Struct but wrong/missing fields + - no_struct: Doesn't use struct + - confused: Wrong approach + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + If correct: + - Perfect struct definition! + - Your struct groups the two payoffs together. + - Now you can create: struct Payoff outcome; + - Access: outcome.player1 = -1; outcome.player2 = -1; + + If correct concept: + - Right idea! Small syntax adjustment: + - Show corrected version. + - Explain the fix. + + If missing fields: + - Remember: need TWO integer fields + - One for player1's payoff + - One for player2's payoff + + If no struct: + - C structs group related data! + - Show example struct format. + buckets: [correct, correct_concept, missing_fields, no_struct, confused, set_language, off_topic] + transitions: + correct: + ai_feedback: + tokens_for_ai: | + Excellent struct definition! + Your Payoff struct elegantly groups both players' outcomes. + Usage: struct Payoff p = {-1, -2}; or p.player1 = 0; + This is the foundation for representing game outcomes! + metadata_add: {score: "n+2", concepts_mastered: "n+1"} + next_section_and_step: structures:step_2 + correct_concept: + ai_feedback: + tokens_for_ai: | + Great concept! Minor syntax refinement: + Show corrected struct. + Explain the adjustment made. + metadata_add: {score: "n+1"} + next_section_and_step: structures:step_2 + missing_fields: + ai_feedback: + tokens_for_ai: | + Need two int fields! + + struct Payoff { + int player1; + int player2; + }; + + This stores both players' payoffs together. + next_section_and_step: structures:step_1 + no_struct: + content_blocks: + - "Use a struct to group the two payoffs:" + - "struct Payoff { ... };" + - "Include two int fields inside the braces" + next_section_and_step: structures:step_1 + confused: + content_blocks: + - "Define a struct with:" + - "- Name: Payoff" + - "- Two int fields (one for each player's payoff)" + - "Don't forget the semicolon at the end!" + next_section_and_step: structures:step_1 + set_language: + metadata_add: {language: "the-users-response"} + counts_as_attempt: false + next_section_and_step: structures:step_1 + off_topic: + next_section_and_step: structures:step_1 + + - step_id: step_2 + title: Payoff Matrix with 2D Array + content_blocks: + - "## 2D Array for Game Matrix 🎯" + - "" + - "**Representing a 2x2 game:**" + - "" + - "**Prisoner's Dilemma has:**" + - "- 2 strategies per player: cooperate (0) or defect (1)" + - "- 4 possible outcomes: (0,0), (0,1), (1,0), (1,1)" + - "" + - "**Perfect for a 2D array!**" + - "" + - "**Array structure:**" + - "- First index: player 1's strategy (0 or 1)" + - "- Second index: player 2's strategy (0 or 1)" + - "- Value: Payoff struct with both payoffs" + - "" + - "**Conceptual mapping:**" + - "```" + - "matrix[0][0] = both cooperate" + - "matrix[0][1] = p1 cooperates, p2 defects" + - "matrix[1][0] = p1 defects, p2 cooperates" + - "matrix[1][1] = both defect" + - "```" + - "" + - "**Array declaration concept:**" + - "You declare a 2D array of your Payoff struct" + - "Then initialize it with the four outcomes" + question: "Declare and initialize a 2D array called 'prisoners_dilemma' of Payoff structs representing the Prisoner's Dilemma game. Use indices 0=cooperate, 1=defect. Payoffs: both cooperate (-1,-1), both defect (-2,-2), one defects (0,-3) or (-3,0)." + tokens_for_ai: | + Looking for 2D array declaration and initialization: + + struct Payoff prisoners_dilemma[2][2] = { + {{-1, -1}, {-3, 0}}, // p1 cooperates + {{0, -3}, {-2, -2}} // p1 defects + }; + + Or similar valid initialization. + + Categorize as: + - correct: Valid 2D array with proper payoffs + - correct_structure: Right format, payoff errors + - wrong_dimensions: Not 2x2 + - syntax_errors: C syntax issues + - confused: Wrong approach + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + If correct: + - Perfect 2D array implementation! + - prisoners_dilemma[0][0] = both cooperate = {-1,-1} + - prisoners_dilemma[1][1] = both defect = {-2,-2} + - prisoners_dilemma[0][1] = p1 cooperate, p2 defect = {-3,0} + - prisoners_dilemma[1][0] = p1 defect, p2 cooperate = {0,-3} + - Efficient memory layout for game representation! + + If structure right: + - Great array structure! Payoff corrections: + - Show corrected initialization. + - Explain the Prisoner's Dilemma payoffs. + + If wrong dimensions: + - Need 2x2 array (2 strategies per player) + - struct Payoff name[2][2] = {...}; + + If syntax errors: + - Show correct C array initialization syntax. + - Explain the nested braces structure. + buckets: [correct, correct_structure, wrong_dimensions, syntax_errors, confused, set_language, off_topic] + transitions: + correct: + ai_feedback: + tokens_for_ai: | + Excellent array implementation! + Your 2D array efficiently represents the payoff matrix. + Access is simple: prisoners_dilemma[i][j] + Memory layout is contiguous and cache-friendly. + This is how game theory simulations optimize performance! + metadata_add: {score: "n+2", concepts_mastered: "n+1"} + next_section_and_step: functions:step_1 + correct_structure: + ai_feedback: + tokens_for_ai: | + Great structure! Payoff corrections for Prisoner's Dilemma: + Show corrected initialization with explanations. + Explain why these specific payoffs create the dilemma. + metadata_add: {score: "n+1"} + next_section_and_step: functions:step_1 + wrong_dimensions: + ai_feedback: + tokens_for_ai: | + Need 2x2 for two-strategy game: + + struct Payoff game[2][2] = { + {{-1,-1}, {-3,0}}, + {{0,-3}, {-2,-2}} + }; + next_section_and_step: structures:step_2 + syntax_errors: + ai_feedback: + tokens_for_ai: | + C array initialization uses nested braces: + + struct Payoff arr[2][2] = { + {row0_col0, row0_col1}, + {row1_col0, row1_col1} + }; + + Each Payoff is {p1_payoff, p2_payoff} + next_section_and_step: structures:step_2 + confused: + content_blocks: + - "Declare: struct Payoff prisoners_dilemma[2][2]" + - "Initialize with nested braces: {{...}, {...}}" + - "Four outcomes total (2x2 = 4 combinations)" + next_section_and_step: structures:step_2 + set_language: + metadata_add: {language: "the-users-response"} + counts_as_attempt: false + next_section_and_step: structures:step_2 + off_topic: + next_section_and_step: structures:step_2 + + - section_id: functions + title: Strategy Functions + steps: + - step_id: step_1 + title: Lookup Function + content_blocks: + - "## Querying the Payoff Matrix 🔍" + - "" + - "**Create a function to get payoffs**" + - "" + - "**Function requirements:**" + - "- Name: `get_payoff`" + - "- Parameters: 2D array (pointer), two strategy indices" + - "- Returns: Payoff struct" + - "" + - "**C function concepts:**" + - "- Pass 2D array as pointer" + - "- Access with array indexing" + - "- Return struct by value" + - "" + - "**What it does:**" + - "Takes strategies (0 or 1 for each player)" + - "Returns the corresponding Payoff from the matrix" + question: "Write a C function called 'get_payoff' that takes a 2D Payoff array (as pointer) and two integer strategy indices, then returns the Payoff struct for that strategy combination." + tokens_for_ai: | + Acceptable function signatures: + - struct Payoff get_payoff(struct Payoff matrix[2][2], int s1, int s2) + - struct Payoff get_payoff(struct Payoff (*matrix)[2], int s1, int s2) + + Function body should: + - Return matrix[s1][s2]; + + Categorize as: + - correct: Valid function with proper syntax + - correct_logic: Right idea, minor syntax + - wrong_return: Doesn't return Payoff struct + - pointer_confusion: Struggles with array parameter + - confused: Wrong approach + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + If correct: + - Perfect function! + - Your function cleanly accesses the 2D array. + - Returning struct by value is simple and safe here. + - Usage: struct Payoff p = get_payoff(game, 0, 1); + + If correct logic: + - Great logic! Minor syntax refinement: + - Show corrected version. + - Explain the C-specific details. + + If wrong return: + - Function should return struct Payoff + - return matrix[s1][s2]; gives you the Payoff struct. + + If pointer confusion: + - For small 2D arrays, can pass as: struct Payoff matrix[2][2] + - Or use pointer: struct Payoff (*matrix)[2] + - Show working example. + buckets: [correct, correct_logic, wrong_return, pointer_confusion, confused, set_language, off_topic] + transitions: + correct: + ai_feedback: + tokens_for_ai: | + Excellent function implementation! + Your get_payoff function cleanly retrieves outcomes. + C's struct return makes this straightforward. + You've encapsulated the lookup logic perfectly! + metadata_add: {score: "n+2", concepts_mastered: "n+1"} + next_section_and_step: simulation:step_1 + correct_logic: + ai_feedback: + tokens_for_ai: | + Great logic! Small C syntax refinement: + Show polished version. + Explain the specific C conventions used. + metadata_add: {score: "n+1"} + next_section_and_step: simulation:step_1 + wrong_return: + ai_feedback: + tokens_for_ai: | + Return type should be struct Payoff: + + struct Payoff get_payoff(struct Payoff matrix[2][2], int s1, int s2) { + return matrix[s1][s2]; + } + next_section_and_step: functions:step_1 + pointer_confusion: + ai_feedback: + tokens_for_ai: | + For 2D array parameter, simple approach: + + struct Payoff get_payoff(struct Payoff matrix[2][2], int s1, int s2) { + return matrix[s1][s2]; + } + + C automatically handles the array as pointer. + next_section_and_step: functions:step_1 + confused: + content_blocks: + - "Function signature: struct Payoff get_payoff(struct Payoff matrix[2][2], int s1, int s2)" + - "Function body: return matrix[s1][s2];" + - "This returns the Payoff at position [s1][s2]" + next_section_and_step: functions:step_1 + set_language: + metadata_add: {language: "the-users-response"} + counts_as_attempt: false + next_section_and_step: functions:step_1 + off_topic: + next_section_and_step: functions:step_1 + + - section_id: simulation + title: Game Simulation + steps: + - step_id: step_1 + title: Strategy Enumeration + content_blocks: + - "## Defining Strategies with Enum 🎲" + - "" + - "**Making code readable:**" + - "Instead of 0 and 1, use named constants!" + - "" + - "**C enum for strategies:**" + - "Enums give names to integer values" + - "" + - "**What you need:**" + - "- Enum name: Strategy (or similar)" + - "- Two values: COOPERATE = 0, DEFECT = 1" + - "" + - "**Why enums improve code:**" + - "- get_payoff(game, COOPERATE, DEFECT) is clearer" + - "- Better than get_payoff(game, 0, 1)" + - "- Self-documenting code" + - "- Type safety (to some degree)" + question: "Define a C enum called 'Strategy' with two values: COOPERATE (equals 0) and DEFECT (equals 1)." + tokens_for_ai: | + Looking for enum definition: + + enum Strategy { + COOPERATE = 0, + DEFECT = 1 + }; + + Or: + typedef enum { + COOPERATE = 0, + DEFECT = 1 + } Strategy; + + Categorize as: + - correct: Valid enum with both values + - correct_concept: Right idea, minor syntax + - missing_values: Enum but wrong values + - no_enum: Doesn't use enum + - confused: Wrong approach + - set_language: Language preference + - off_topic: Unrelated + feedback_tokens_for_ai: | + If correct: + - Perfect enum definition! + - Now you can write: enum Strategy s = COOPERATE; + - Much more readable than: int s = 0; + - Self-documenting code is maintainable code! + + If correct concept: + - Great use of enum! Small refinement: + - Show corrected version. + + If missing values: + - Need both COOPERATE = 0 and DEFECT = 1 + - Show correct enum. + + If no enum: + - C enums create named integer constants: + - Show enum syntax. + buckets: [correct, correct_concept, missing_values, no_enum, confused, set_language, off_topic] + transitions: + correct: + ai_feedback: + tokens_for_ai: | + Excellent enum! + Your code is now self-documenting. + COOPERATE and DEFECT are much clearer than 0 and 1. + This is professional C code style! + You've mastered game theory implementation in C! + metadata_add: {score: "n+2", concepts_mastered: "n+1", activity_completed: "true"} + correct_concept: + ai_feedback: + tokens_for_ai: | + Great enum concept! Small polish: + Show refined version. + You understand C enums well! + metadata_add: {score: "n+1", activity_completed: "true"} + missing_values: + ai_feedback: + tokens_for_ai: | + Need both strategies: + + enum Strategy { + COOPERATE = 0, + DEFECT = 1 + }; + next_section_and_step: simulation:step_1 + no_enum: + content_blocks: + - "Define enum with:" + - "enum Strategy { COOPERATE = 0, DEFECT = 1 };" + - "This creates named constants" + next_section_and_step: simulation:step_1 + confused: + content_blocks: + - "Enum syntax: enum Name { VALUE1 = 0, VALUE2 = 1 };" + - "Creates named integer constants" + - "Don't forget the semicolon!" + next_section_and_step: simulation:step_1 + set_language: + metadata_add: {language: "the-users-response"} + counts_as_attempt: false + next_section_and_step: simulation:step_1 + off_topic: + metadata_add: {activity_completed: "true"} From fd6360d7d8364819f1ddee17e7587274dc2e2f7d Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 9 Nov 2025 16:07:15 +0000 Subject: [PATCH 7/7] Add 4 advanced programming activities with algorithm education NEW ACTIVITIES: activity48-monty-hall-simulation.yaml - Monty Hall paradox proof - Simulate stay vs switch strategies - Prove switching wins 2/3 through code - Any programming language support activity49-multi-armed-bandit.yaml - Adaptive algorithms beat A/B testing - Epsilon-greedy implementation - 88% regret reduction vs traditional A/B - Real-world applications (web optimization, clinical trials) activity50-genetic-algorithms.yaml - Evolution-based optimization - String evolution challenge - Fitness, selection, crossover, mutation - 803,181x faster than brute force activity51-connect-four.yaml - Complete game development - 2D arrays and game state - Win detection algorithms (horizontal, vertical, diagonal) - Full game loop implementation All activities: - Support ANY programming language choice - Follow pedagogical best practices (concepts first, code in feedback) - Validate with zero errors/warnings - Engaging and fun (aha moments, real games, simulations) --- .../activity48-monty-hall-simulation.yaml | 663 ++++++++++++ research/activity49-multi-armed-bandit.yaml | 645 ++++++++++++ research/activity50-genetic-algorithms.yaml | 861 ++++++++++++++++ research/activity51-connect-four.yaml | 964 ++++++++++++++++++ 4 files changed, 3133 insertions(+) create mode 100644 research/activity48-monty-hall-simulation.yaml create mode 100644 research/activity49-multi-armed-bandit.yaml create mode 100644 research/activity50-genetic-algorithms.yaml create mode 100644 research/activity51-connect-four.yaml diff --git a/research/activity48-monty-hall-simulation.yaml b/research/activity48-monty-hall-simulation.yaml new file mode 100644 index 0000000..9da3b79 --- /dev/null +++ b/research/activity48-monty-hall-simulation.yaml @@ -0,0 +1,663 @@ +default_max_attempts_per_step: 3 +classifier_model: "MODEL_1" +feedback_model: "MODEL_1" + +tokens_for_ai_rubric: | + You are teaching the Monty Hall problem through programming simulation. + The user's chosen programming language is stored in metadata.programming_language. + ALWAYS provide feedback and code examples in THEIR chosen language. + Be encouraging and help them discover the counterintuitive truth through code. + +sections: + - section_id: "introduction" + title: "Introduction" + steps: + - step_id: "welcome" + title: "Welcome to Monty Hall Simulation" + content_blocks: + - "# Welcome to the Monty Hall Paradox! 🚪🐐🚗" + - "" + - "You're about to explore one of the most **counterintuitive** problems in probability." + - "" + - "We'll use **programming** to prove a mathematical truth that most people find hard to believe!" + - "" + - "**What you'll learn:**" + - "- The famous Monty Hall problem" + - "- How to simulate probability with code" + - "- Why our intuition fails us" + - "- Random number generation, loops, and counters" + - "" + - "Let's get started! 🎲" + + - step_id: "choose_language" + title: "Choose Your Programming Language" + question: "What programming language would you like to use? (e.g., Python, JavaScript, C, Java, Go, Rust, etc.)" + tokens_for_ai: | + The user is choosing their programming language for this activity. + + Categorize as 'valid_language' if they name a real programming language. + Examples: Python, JavaScript, C, C++, Java, Go, Rust, Ruby, PHP, Swift, Kotlin, etc. + + Categorize as 'set_language' if they're asking to change the conversation language. + + Categorize as 'need_help' if they seem unsure or ask for recommendations. + buckets: [valid_language, set_language, need_help] + transitions: + valid_language: + ai_feedback: + tokens_for_ai: | + Acknowledge their language choice enthusiastically! + Tell them it's a great choice for simulation. + Store the EXACT language name they said in metadata.programming_language. + metadata_add: + programming_language: "the-users-response" + next_section_and_step: "monty_hall_problem:explain_problem" + set_language: + content_blocks: + - "Language preference updated. Now, what programming language would you like to code in?" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: "introduction:choose_language" + need_help: + content_blocks: + - "**Popular choices for beginners:**" + - "- **Python** - Easy to read, great for learning" + - "- **JavaScript** - Runs in browsers, very accessible" + - "- **C** - Classic, teaches fundamentals" + - "" + - "**For experienced programmers:**" + - "- **Java** - Object-oriented, widely used" + - "- **Go** - Modern, simple, efficient" + - "- **Rust** - Safe, fast, challenging" + - "" + - "Which would you like to use?" + counts_as_attempt: false + next_section_and_step: "introduction:choose_language" + + - section_id: "monty_hall_problem" + title: "The Monty Hall Problem" + steps: + - step_id: "explain_problem" + title: "The Game Show Scenario" + content_blocks: + - "# The Monty Hall Problem 🎭" + - "" + - "Imagine you're on a game show:" + - "" + - "1. **Three doors** are in front of you: 🚪 🚪 🚪" + - "2. Behind **one door** is a **car** 🚗 (the prize!)" + - "3. Behind the **other two** are **goats** 🐐🐐 (not prizes)" + - "" + - "**The Game:**" + - "- You pick a door (say Door #1)" + - "- The host (Monty Hall) **knows** where the car is" + - "- Monty opens one of the OTHER doors, revealing a goat" + - "- Monty asks: **\"Do you want to SWITCH to the other unopened door?\"**" + - "" + - "**The Question:**" + - "Should you STAY with your original choice, or SWITCH to the other door?" + + - step_id: "intuition_check" + title: "What's Your Intuition?" + question: "What do you think? Should you STAY with your original door, SWITCH to the other door, or does it NOT MATTER (50/50 odds)?" + tokens_for_ai: | + The user is giving their intuitive answer to the Monty Hall problem. + + Categorize as 'stay' if they think staying is better. + Categorize as 'switch' if they think switching is better. + Categorize as 'same_odds' if they think it doesn't matter (50/50). + Categorize as 'set_language' if asking to change conversation language. + Categorize as 'unsure' if they don't know or want more explanation. + buckets: [stay, switch, same_odds, set_language, unsure] + transitions: + stay: + content_blocks: + - "Interesting! That's a common intuition." + - "" + - "Many people think staying is just as good as switching." + - "" + - "Let's find out if you're right... through CODE! 🔬" + metadata_add: + initial_intuition: "stay" + next_section_and_step: "probability_prediction:predict_probabilities" + switch: + content_blocks: + - "Aha! You might be onto something! 🤔" + - "" + - "That's actually the counterintuitive answer that most people reject at first." + - "" + - "Let's prove it with code! 💻" + metadata_add: + initial_intuition: "switch" + next_section_and_step: "probability_prediction:predict_probabilities" + same_odds: + content_blocks: + - "That's what most people think! It FEELS like 50/50, right?" + - "" + - "After all, there are two doors left... seems like equal odds." + - "" + - "But prepare to have your mind blown! 🤯" + metadata_add: + initial_intuition: "same_odds" + next_section_and_step: "probability_prediction:predict_probabilities" + set_language: + content_blocks: + - "Language preference updated." + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: "monty_hall_problem:intuition_check" + unsure: + content_blocks: + - "No problem! This is a VERY tricky problem." + - "" + - "Even famous mathematicians got it wrong at first!" + - "" + - "Let's discover the answer together through simulation. 🧪" + metadata_add: + initial_intuition: "unsure" + next_section_and_step: "probability_prediction:predict_probabilities" + + - section_id: "probability_prediction" + title: "Probability Prediction" + steps: + - step_id: "predict_probabilities" + title: "Predict the Win Rates" + question: | + Before we code, make a prediction: + + If you play this game 1000 times... + + - What % of the time will STAYING win? + - What % of the time will SWITCHING win? + + Give your prediction (e.g., "50% stay, 50% switch" or "33% stay, 67% switch") + tokens_for_ai: | + The user is predicting the win rates for stay vs switch strategies. + + The CORRECT answer is: ~33% stay wins, ~67% switch wins (or 1/3 vs 2/3). + + Categorize as 'correct_prediction' if they predict something close to 33/67 or 1/3 vs 2/3. + Categorize as 'incorrect_prediction' for any other prediction (like 50/50). + Categorize as 'set_language' if asking to change conversation language. + Categorize as 'unsure' if they don't want to guess. + buckets: [correct_prediction, incorrect_prediction, set_language, unsure] + transitions: + correct_prediction: + content_blocks: + - "Wow! You predicted correctly! 🎯" + - "" + - "**The answer:** Switching wins ~67% of the time (2/3)!" + - "" + - "Most people find this SHOCKING. Let's prove it with code!" + metadata_add: + prediction: "the-users-response" + predicted_correctly: "true" + next_section_and_step: "implement_stay:explain_stay_strategy" + incorrect_prediction: + content_blocks: + - "Good guess! That's what most people predict." + - "" + - "But here's the truth: **Switching wins ~67% of the time (2/3)!** 🤯" + - "" + - "I know, I know... it seems impossible." + - "" + - "That's why we're going to PROVE it with simulation! Let's code it up! 💻" + metadata_add: + prediction: "the-users-response" + predicted_correctly: "false" + next_section_and_step: "implement_stay:explain_stay_strategy" + set_language: + content_blocks: + - "Language preference updated." + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: "probability_prediction:predict_probabilities" + unsure: + content_blocks: + - "No worries! The math is tricky." + - "" + - "Here's the answer: **Switching wins ~67% of the time (2/3)!**" + - "" + - "Sounds crazy, right? Let's prove it with code! 💻" + metadata_add: + prediction: "unsure" + next_section_and_step: "implement_stay:explain_stay_strategy" + + - section_id: "implement_stay" + title: "Implement the Stay Strategy" + steps: + - step_id: "explain_stay_strategy" + title: "Understanding the Stay Strategy" + content_blocks: + - "# Simulating the STAY Strategy 🎲" + - "" + - "Let's start by simulating what happens when you ALWAYS stay with your first choice." + - "" + - "**The Algorithm:**" + - "1. Randomly place the car behind one of 3 doors (1, 2, or 3)" + - "2. Player randomly picks a door (1, 2, or 3)" + - "3. If player's door == car's door, they WIN" + - "4. Otherwise, they LOSE" + - "5. Repeat this 1000 times" + - "6. Calculate: (wins / 1000) × 100 = win percentage" + - "" + - "**Key Concepts:**" + - "- **Random number generation** (pick 1, 2, or 3 randomly)" + - "- **Loop** (repeat 1000 times)" + - "- **Counter** (track wins)" + - "- **Conditional** (if door matches, increment wins)" + - "" + - "Note: We don't need to simulate Monty opening a door for the STAY strategy, because the player never switches!" + + - step_id: "code_stay_strategy" + title: "Code the Stay Strategy" + question: | + Write a program that simulates the STAY strategy. + + Your program should: + - Run 1000 trials + - In each trial, randomly pick where the car is (1-3) and where the player picks (1-3) + - Count wins when they match + - Print the win percentage + + Share your code! + tokens_for_ai: | + The user is writing code to simulate the STAY strategy in Monty Hall. + Their programming language is: metadata.programming_language + + Check if their code demonstrates: + 1. Random number generation (picking 1-3 for car and player) + 2. A loop running many trials (doesn't have to be exactly 1000) + 3. A counter for wins + 4. Comparison logic (if car_door == player_door, count as win) + 5. Calculating/printing win percentage + + Categorize as 'correct_code' if they have all 5 elements (even if syntax has minor issues). + Categorize as 'partial_code' if they have 3-4 elements or the right idea but incomplete. + Categorize as 'needs_help' if they're stuck, have major errors, or ask for help. + Categorize as 'set_language' if asking to change conversation language. + Categorize as 'off_topic' if completely unrelated. + feedback_tokens_for_ai: | + The user's programming language is: metadata.programming_language + + If they wrote correct code: + - Praise their implementation! + - Point out what they did well (random generation, loop structure, etc.) + - If they ran it, acknowledge their results (should be ~33%) + - Provide a CLEAN, COMPLETE working example in their language showing best practices + - Encourage them: "Great! Now let's implement the SWITCH strategy!" + + If they wrote partial code: + - Acknowledge what they got right + - Gently point out what's missing (e.g., "You have the loop, but how do you pick random doors?") + - Give a helpful hint in their specific language + - Encourage them to complete it + + If they need help: + - Be encouraging! + - Provide a complete working example in their language + - Explain each part clearly + - Ask them to try running it + buckets: [correct_code, partial_code, needs_help, set_language, off_topic] + transitions: + correct_code: + ai_feedback: + tokens_for_ai: "User wrote correct code - see feedback_tokens_for_ai above" + metadata_add: + stay_strategy_completed: "true" + next_section_and_step: "implement_switch:explain_switch_strategy" + partial_code: + ai_feedback: + tokens_for_ai: "User wrote partial code - see feedback_tokens_for_ai above" + counts_as_attempt: true + next_section_and_step: "implement_stay:code_stay_strategy" + needs_help: + ai_feedback: + tokens_for_ai: "User needs help - see feedback_tokens_for_ai above" + counts_as_attempt: false + next_section_and_step: "implement_stay:code_stay_strategy" + set_language: + content_blocks: + - "Language preference updated." + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: "implement_stay:code_stay_strategy" + off_topic: + content_blocks: + - "Let's focus on implementing the stay strategy simulation." + - "Share your code for simulating 1000 trials of staying with your first choice!" + counts_as_attempt: false + next_section_and_step: "implement_stay:code_stay_strategy" + + - section_id: "implement_switch" + title: "Implement the Switch Strategy" + steps: + - step_id: "explain_switch_strategy" + title: "Understanding the Switch Strategy" + content_blocks: + - "# Simulating the SWITCH Strategy 🔄" + - "" + - "Now for the interesting part: simulating what happens when you ALWAYS switch!" + - "" + - "**The Algorithm:**" + - "1. Randomly place the car behind one of 3 doors (1, 2, or 3)" + - "2. Player randomly picks a door (1, 2, or 3)" + - "3. Monty opens one of the OTHER doors that has a goat" + - " - Monty won't open the car door" + - " - Monty won't open the player's door" + - "4. Player switches to the remaining unopened door" + - "5. If the switched door has the car, they WIN" + - "6. Repeat 1000 times and calculate win percentage" + - "" + - "**Key Insight:**" + - "When you switch, you win if your FIRST choice was WRONG." + - "Since you're wrong 2/3 of the time initially, switching wins 2/3 of the time!" + - "" + - "**Simplification:**" + - "You can actually implement this without simulating Monty's choice!" + - "Just check: if player_first_choice != car_door, then switching wins." + - "Why? Because if you picked wrong initially, the remaining door MUST have the car!" + + - step_id: "code_switch_strategy" + title: "Code the Switch Strategy" + question: | + Write a program that simulates the SWITCH strategy. + + Your program should: + - Run 1000 trials + - In each trial, randomly place the car and player's initial choice + - Determine if switching would win (switching wins when initial choice was wrong!) + - Count wins and print the win percentage + + Share your code! + tokens_for_ai: | + The user is writing code to simulate the SWITCH strategy in Monty Hall. + Their programming language is: metadata.programming_language + + Check if their code demonstrates: + 1. Random number generation (picking 1-3 for car and initial player choice) + 2. A loop running many trials + 3. A counter for wins + 4. Logic that switching wins when initial choice != car door + 5. Calculating/printing win percentage + + They might implement it in two ways: + - Simple: if first_choice != car_door, then win (because switch gets the car) + - Complex: Actually simulate Monty opening a door and switching to remaining door + + Both are correct! + + Categorize as 'correct_code' if they have the right logic. + Categorize as 'partial_code' if they have the right idea but incomplete. + Categorize as 'needs_help' if they're stuck or have major errors. + Categorize as 'set_language' if asking to change conversation language. + Categorize as 'off_topic' if completely unrelated. + feedback_tokens_for_ai: | + The user's programming language is: metadata.programming_language + + If they wrote correct code: + - Celebrate! This is the key insight! + - Praise their implementation + - If they ran it, acknowledge results (should be ~67%) + - Provide a clean, complete working example in their language + - Point out the beautiful insight: "Switching wins when you're initially wrong (2/3 of the time)!" + - Encourage them to compare both strategies + + If they wrote partial code: + - Acknowledge what they got right + - Hint: "Remember, switching wins when your FIRST choice was WRONG" + - Help them complete it + + If they need help: + - Be encouraging! + - Provide a complete working example + - Explain the key insight clearly + buckets: [correct_code, partial_code, needs_help, set_language, off_topic] + transitions: + correct_code: + ai_feedback: + tokens_for_ai: "User wrote correct code - see feedback_tokens_for_ai above" + metadata_add: + switch_strategy_completed: "true" + next_section_and_step: "run_simulations:compare_results" + partial_code: + ai_feedback: + tokens_for_ai: "User wrote partial code - see feedback_tokens_for_ai above" + counts_as_attempt: true + next_section_and_step: "implement_switch:code_switch_strategy" + needs_help: + ai_feedback: + tokens_for_ai: "User needs help - see feedback_tokens_for_ai above" + counts_as_attempt: false + next_section_and_step: "implement_switch:code_switch_strategy" + set_language: + content_blocks: + - "Language preference updated." + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: "implement_switch:code_switch_strategy" + off_topic: + content_blocks: + - "Let's focus on implementing the switch strategy simulation." + - "Share your code for simulating what happens when you always switch!" + counts_as_attempt: false + next_section_and_step: "implement_switch:code_switch_strategy" + + - section_id: "run_simulations" + title: "Run and Compare Simulations" + steps: + - step_id: "compare_results" + title: "Compare the Strategies" + question: | + Now run BOTH simulations and compare the results! + + Run each simulation with at least 1000 trials (more is better - try 10,000!). + + Report back: + - What % does STAY win? + - What % does SWITCH win? + - What do you observe? + tokens_for_ai: | + The user is reporting results from running both simulations. + + The expected results are: + - STAY wins ~33% (approximately 1/3) + - SWITCH wins ~67% (approximately 2/3) + + Categorize as 'correct_results' if they report something close to these percentages. + Accept anything in ranges: STAY 30-36%, SWITCH 64-70% + + Categorize as 'incorrect_results' if their numbers are way off (suggesting bugs in code). + + Categorize as 'needs_help' if they couldn't run it or had errors. + + Categorize as 'set_language' if asking to change conversation language. + + Categorize as 'insightful' if they not only report numbers but also express the "aha!" insight. + buckets: [correct_results, incorrect_results, insightful, needs_help, set_language] + transitions: + correct_results: + content_blocks: + - "**AMAZING!** 🎉" + - "" + - "You've proven it with code:" + - "- STAY wins ~33% (1 out of 3 times)" + - "- SWITCH wins ~67% (2 out of 3 times)" + - "" + - "**Switching DOUBLES your chances of winning!**" + - "" + - "This is the Monty Hall paradox - counterintuitive but mathematically proven!" + metadata_add: + simulations_completed: "true" + next_section_and_step: "reflection:reflect_on_why" + incorrect_results: + content_blocks: + - "Hmm, those numbers don't look quite right." + - "" + - "Expected results:" + - "- STAY should win ~33%" + - "- SWITCH should win ~67%" + - "" + - "There might be a bug in your code. Want to review the logic?" + counts_as_attempt: true + next_section_and_step: "run_simulations:compare_results" + insightful: + content_blocks: + - "**YES! You've got it!** 🤯✨" + - "" + - "You've not only proven it with code, but you UNDERSTAND why!" + - "" + - "**The key insight:**" + - "Switching wins when your first choice was wrong (2/3 of the time)!" + - "" + - "Beautiful work! 🎊" + metadata_add: + simulations_completed: "true" + deep_understanding: "true" + next_section_and_step: "reflection:reflect_on_why" + needs_help: + content_blocks: + - "No problem! Let's troubleshoot." + - "" + - "Make sure both simulations:" + - "1. Run enough trials (1000+)" + - "2. Use proper random number generation" + - "3. Have correct win conditions" + - "" + - "Try running them again, or share any errors you're seeing!" + counts_as_attempt: false + next_section_and_step: "run_simulations:compare_results" + set_language: + content_blocks: + - "Language preference updated." + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: "run_simulations:compare_results" + + - section_id: "reflection" + title: "Reflection and Understanding" + steps: + - step_id: "reflect_on_why" + title: "Why Does Switching Win?" + question: | + You've seen the proof in code: switching wins ~67% of the time. + + But WHY? Can you explain in your own words why switching is better than staying? + + Think about it and share your explanation! + tokens_for_ai: | + The user is explaining why switching wins in the Monty Hall problem. + + Good explanations mention: + - Initially, you have a 1/3 chance of picking the car (2/3 chance of picking a goat) + - Monty ALWAYS reveals a goat from the doors you didn't pick + - If you picked a goat initially (2/3 probability), the remaining door MUST have the car + - So switching wins whenever you initially picked a goat (2/3 of the time) + + Categorize as 'excellent_explanation' if they demonstrate deep understanding. + Categorize as 'good_explanation' if they get the main idea right. + Categorize as 'partial_explanation' if they're on the right track but missing key insights. + Categorize as 'set_language' if asking to change conversation language. + Categorize as 'needs_help' if they're still confused. + feedback_tokens_for_ai: | + Provide encouraging, detailed feedback on their explanation. + + If excellent/good: + - Celebrate their understanding! + - Reinforce the key insights they mentioned + - Add any nuances they might have missed + - Congratulate them on conquering this famous paradox! + + If partial: + - Acknowledge what they got right + - Gently fill in the missing pieces + - Use clear examples + + If needs help: + - Be patient and encouraging + - Explain step by step: + 1. You pick a door (1/3 chance of car, 2/3 chance of goat) + 2. Monty opens a goat door from the OTHER two doors + 3. If you picked a goat (2/3 probability), the remaining door has the car + 4. So switching wins 2/3 of the time! + buckets: [excellent_explanation, good_explanation, partial_explanation, set_language, needs_help] + transitions: + excellent_explanation: + ai_feedback: + tokens_for_ai: "User has excellent understanding - see feedback_tokens_for_ai" + metadata_add: + activity_completed: "true" + understanding_level: "excellent" + next_section_and_step: "reflection:conclusion" + good_explanation: + ai_feedback: + tokens_for_ai: "User has good understanding - see feedback_tokens_for_ai" + metadata_add: + activity_completed: "true" + understanding_level: "good" + next_section_and_step: "reflection:conclusion" + partial_explanation: + ai_feedback: + tokens_for_ai: "User has partial understanding - see feedback_tokens_for_ai" + metadata_add: + activity_completed: "true" + understanding_level: "partial" + next_section_and_step: "reflection:conclusion" + set_language: + content_blocks: + - "Language preference updated." + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: "reflection:reflect_on_why" + needs_help: + ai_feedback: + tokens_for_ai: "User needs help understanding - see feedback_tokens_for_ai" + metadata_add: + activity_completed: "true" + understanding_level: "needs_review" + next_section_and_step: "reflection:conclusion" + + - step_id: "conclusion" + title: "Congratulations!" + content_blocks: + - "# 🎊 Congratulations! 🎊" + - "" + - "You've conquered the **Monty Hall Paradox** through programming!" + - "" + - "## What You've Learned:" + - "" + - "✅ **Probability can be counterintuitive** - our gut feelings often fail us" + - "" + - "✅ **Simulation proves theory** - running 1000s of trials reveals mathematical truth" + - "" + - "✅ **Programming concepts:**" + - " - Random number generation" + - " - Loops and iteration" + - " - Counters and accumulation" + - " - Conditional logic" + - "" + - "✅ **The Monty Hall insight:** Switching wins 2/3 of the time because you win whenever your initial choice was wrong (which happens 2/3 of the time)!" + - "" + - "## Fun Facts:" + - "" + - "- This problem stumped thousands of people, including many mathematicians!" + - "- It's named after Monty Hall, host of \"Let's Make a Deal\"" + - "- Even when shown the math, many people still don't believe it - but your code doesn't lie! 📊" + - "" + - "## Next Steps:" + - "" + - "- Try increasing trials to 100,000 or 1,000,000" + - "- Visualize the results with graphs" + - "- Explore other probability paradoxes" + - "- Share this mind-blowing result with friends!" + - "" + - "**Thank you for exploring this fascinating paradox!** 🚪🐐🚗" + - "" + - "May your code always compile and your probabilities always surprise you! ✨" diff --git a/research/activity49-multi-armed-bandit.yaml b/research/activity49-multi-armed-bandit.yaml new file mode 100644 index 0000000..86c86a9 --- /dev/null +++ b/research/activity49-multi-armed-bandit.yaml @@ -0,0 +1,645 @@ +default_max_attempts_per_step: 3 +classifier_model: "MODEL_1" +feedback_model: "MODEL_3" # Use code model for programming feedback + +tokens_for_ai_rubric: | + You are teaching the multi-armed bandit algorithm to a student. + The student has chosen their programming language stored in metadata.programming_language. + Always provide feedback in THAT specific language. + Be enthusiastic about the gambling/casino metaphor - it makes statistics fun! + Encourage exploration of the exploration vs exploitation tradeoff. + +sections: + - section_id: "introduction" + title: "Welcome to the Casino!" + steps: + - step_id: "welcome" + title: "Welcome" + content_blocks: + - "# 🎰 Welcome to Multi-Armed Bandits! 🎰" + - "" + - "Imagine you're in a casino with multiple slot machines (called 'bandits')." + - "Each machine has a different (unknown) payout rate." + - "" + - "**Your goal:** Maximize your winnings by finding the best machine!" + - "" + - "**The challenge:** You don't know which machine is best until you try them." + - "" + - "Should you keep trying all machines equally (exploration)?" + - "Or focus on the best one you've found so far (exploitation)?" + - "" + - "This is the **exploration vs exploitation tradeoff** - one of the most important problems in machine learning!" + + - step_id: "choose_language" + title: "Choose Your Programming Language" + question: "What programming language would you like to use for this activity? (Python, JavaScript, Java, C++, Go, Rust, or any other language you prefer)" + tokens_for_ai: | + Extract the programming language from the user's response. + Accept any reasonable programming language mention. + + Categorize as 'language_selected' if they mention a programming language. + Categorize as 'set_language' if they want to change the conversation language. + Categorize as 'unclear' if you can't determine the language. + buckets: [language_selected, set_language, unclear] + transitions: + language_selected: + metadata_add: + programming_language: "the-users-response" + content_blocks: + - "Great choice! We'll use that language throughout this activity." + - "" + - "Let's dive into the problem! 🎰" + next_section_and_step: "problem:casino_scenario" + set_language: + metadata_add: + language: "the-users-response" + content_blocks: + - "Language preference updated. Now, which programming language would you like to use for coding?" + counts_as_attempt: false + next_section_and_step: "introduction:choose_language" + unclear: + content_blocks: + - "I didn't catch which programming language you'd like to use." + - "Please specify: Python, JavaScript, Java, C++, Ruby, Go, etc." + next_section_and_step: "introduction:choose_language" + + - section_id: "problem" + title: "Understanding the Problem" + steps: + - step_id: "casino_scenario" + title: "The Casino Scenario" + content_blocks: + - "# 🎰 The Multi-Armed Bandit Problem" + - "" + - "You're in a casino with **3 slot machines**." + - "" + - "**Machine A:** Unknown win rate (let's say it's actually 30%)" + - "**Machine B:** Unknown win rate (let's say it's actually 50%)" + - "**Machine C:** Unknown win rate (let's say it's actually 20%)" + - "" + - "You have **100 coins** to play." + - "Each pull costs 1 coin and might win you 1 coin back (net zero) or lose it (net -1)." + - "" + - "**The catch:** You DON'T know the true win rates!" + - "You have to learn them by playing." + - "" + - "**Real-world applications:**" + - "- Website A/B testing (which button converts better?)" + - "- Online advertising (which ad gets more clicks?)" + - "- Clinical trials (which treatment works better?)" + - "- Recommendation systems (which content keeps users engaged?)" + + - step_id: "understand_problem" + title: "Understanding Check" + question: "In your own words, what is the main challenge of the multi-armed bandit problem?" + tokens_for_ai: | + The student should understand the exploration vs exploitation tradeoff. + + Categorize as 'excellent' if they mention: + - Balancing exploration (trying different options) and exploitation (using the best known option) + - Not knowing which option is best initially + - Learning while optimizing + + Categorize as 'good' if they mention: + - Finding the best option + - Learning from limited attempts + + Categorize as 'set_language' if requesting language change. + Categorize as 'needs_help' otherwise. + buckets: [excellent, good, set_language, needs_help] + transitions: + excellent: + ai_feedback: + tokens_for_ai: | + Enthusiastically praise their understanding! + Highlight the specific insight they showed about exploration vs exploitation. + Get them excited about solving this problem. + Use emojis! 🎰🎯 + next_section_and_step: "ab_testing:naive_approach" + good: + ai_feedback: + tokens_for_ai: | + Praise what they got right. + Gently clarify the exploration vs exploitation tradeoff. + Encourage them forward. + next_section_and_step: "ab_testing:naive_approach" + set_language: + metadata_add: + language: "the-users-response" + content_blocks: + - "Language preference updated." + counts_as_attempt: false + next_section_and_step: "problem:understand_problem" + needs_help: + content_blocks: + - "**Hint:** Think about the tradeoff between:" + - "- **Exploration:** Trying different machines to learn their rates" + - "- **Exploitation:** Using the best machine you've found so far" + - "" + - "If you only explore, you waste coins on bad machines." + - "If you only exploit, you might miss an even better machine!" + next_section_and_step: "problem:understand_problem" + + - section_id: "ab_testing" + title: "Traditional A/B Testing" + steps: + - step_id: "naive_approach" + title: "The Naive Approach" + content_blocks: + - "# 📊 Traditional A/B Testing (The Wasteful Way)" + - "" + - "The traditional approach: **Split traffic evenly!**" + - "" + - "With 100 coins and 3 machines:" + - "- Pull Machine A: 33 times" + - "- Pull Machine B: 33 times" + - "- Pull Machine C: 34 times" + - "" + - "Then analyze results and pick the winner." + - "" + - "**Sounds fair, right?** 🤔" + - "" + - "**But wait...** What if Machine C is terrible (20% win rate)?" + - "You just wasted 34 coins learning what you could have learned after 5 pulls!" + - "" + - "**The problem with A/B testing:**" + - "- Keeps pulling losing arms even after you know they're bad" + - "- Wastes resources (users, ad budget, medical treatments)" + - "- Takes longer to reach optimal decision" + - "" + - "Let's implement this to see the waste in action!" + + - step_id: "implement_ab_test" + title: "Implement A/B Test Simulation" + question: | + Write code that simulates a traditional A/B test with 3 slot machines. + + Requirements: + - 3 machines with true win rates: [0.3, 0.5, 0.2] + - 100 total pulls, split evenly (33, 33, 34) + - Track wins and losses for each machine + - Calculate and print the estimated win rate for each machine + - Calculate total reward (wins - losses) + + Don't worry about perfect code - focus on the logic! + tokens_for_ai: | + The student is implementing a basic A/B test simulation in their chosen language (metadata.programming_language). + + Check if their code includes: + - Arrays/lists to track performance + - Random number generation for simulating pulls + - Even split of pulls across machines + - Calculation of win rates + - Total reward tracking + + Categorize as 'excellent' if code is complete and correct. + Categorize as 'good_attempt' if logic is mostly right but has minor issues. + Categorize as 'needs_guidance' if they're struggling with the structure. + Categorize as 'set_language' if requesting language change. + Categorize as 'wrong_language' if they used a different programming language than stored in metadata. + feedback_tokens_for_ai: | + Provide feedback in their chosen language: {metadata.programming_language} + + If excellent: Praise their implementation! Run through what happens: + - Machine A gets pulled 33 times, wins ~10 times (30%) + - Machine B gets pulled 33 times, wins ~16 times (50%) + - Machine C gets pulled 34 times, wins ~7 times (20%) + - Total reward is negative (you lose money overall) + - Point out: We kept pulling bad machines even after learning they're bad! + + If good_attempt: Point out what's good, fix specific issues, provide corrected code. + + If needs_guidance: Provide a complete working example with detailed comments. + Explain each part: random simulation, tracking, calculating rates. + + If wrong_language: Gently remind them they chose {metadata.programming_language}. + Provide the code in the correct language. + buckets: [excellent, good_attempt, needs_guidance, set_language, wrong_language] + transitions: + excellent: + ai_feedback: + tokens_for_ai: "Use feedback_tokens_for_ai instructions for excellent case" + metadata_add: + ab_test_completed: "true" + next_section_and_step: "waste:see_the_waste" + good_attempt: + ai_feedback: + tokens_for_ai: "Use feedback_tokens_for_ai instructions for good_attempt case" + metadata_add: + ab_test_completed: "true" + next_section_and_step: "waste:see_the_waste" + needs_guidance: + ai_feedback: + tokens_for_ai: "Use feedback_tokens_for_ai instructions for needs_guidance case" + counts_as_attempt: false + next_section_and_step: "ab_testing:implement_ab_test" + set_language: + metadata_add: + language: "the-users-response" + content_blocks: + - "Language preference updated." + counts_as_attempt: false + next_section_and_step: "ab_testing:implement_ab_test" + wrong_language: + ai_feedback: + tokens_for_ai: "Use feedback_tokens_for_ai instructions for wrong_language case" + counts_as_attempt: false + next_section_and_step: "ab_testing:implement_ab_test" + + - section_id: "waste" + title: "Understanding the Waste" + steps: + - step_id: "see_the_waste" + title: "The Waste of A/B Testing" + content_blocks: + - "# 💸 The Waste of Traditional A/B Testing" + - "" + - "Let's see what happens in your A/B test simulation:" + - "" + - "**After 10 pulls of each machine, you might observe:**" + - "- Machine A: 3 wins (30% estimated)" + - "- Machine B: 5 wins (50% estimated)" + - "- Machine C: 2 wins (20% estimated)" + - "" + - "**You now know Machine B is best!** 🎯" + - "" + - "**But traditional A/B testing continues:**" + - "- Pulls Machine A: 23 more times (waste!)" + - "- Pulls Machine B: 23 more times (good!)" + - "- Pulls Machine C: 24 more times (waste!)" + - "" + - "You wasted ~47 pulls on machines you KNEW were inferior!" + - "" + - "**Cumulative regret:** The total loss from not always choosing the best option." + - "" + - "In A/B testing: HIGH regret (you keep pulling losing arms)" + - "In bandit algorithms: LOW regret (you adapt and focus on winners)" + + - step_id: "understand_regret" + title: "Understanding Regret" + question: "Why does traditional A/B testing accumulate more regret than an adaptive algorithm?" + tokens_for_ai: | + Check if student understands that A/B testing: + - Continues pulling all arms equally even after learning which is best + - Doesn't adapt based on observations + - Wastes resources on known-bad options + + Categorize as 'excellent' if they clearly explain the adaptive vs non-adaptive difference. + Categorize as 'good' if they understand but less clearly. + Categorize as 'set_language' if requesting language change. + Categorize as 'needs_clarity' otherwise. + buckets: [excellent, good, set_language, needs_clarity] + transitions: + excellent: + ai_feedback: + tokens_for_ai: | + Celebrate their understanding! 🎉 + Emphasize: Adaptive algorithms LEARN and SHIFT resources to winners. + Get them excited to implement epsilon-greedy! + next_section_and_step: "epsilon_greedy:introduce_algorithm" + good: + ai_feedback: + tokens_for_ai: | + Praise their understanding. + Clarify: The key is ADAPTATION - shifting pulls to better arms as you learn. + next_section_and_step: "epsilon_greedy:introduce_algorithm" + set_language: + metadata_add: + language: "the-users-response" + content_blocks: + - "Language preference updated." + counts_as_attempt: false + next_section_and_step: "waste:understand_regret" + needs_clarity: + content_blocks: + - "**Think about it this way:**" + - "" + - "**A/B Testing:** Pulls each arm 33 times, no matter what you learn" + - "**Adaptive Algorithm:** Pulls good arms MORE as you learn they're good" + - "" + - "If you learn Machine B is best after 10 pulls, wouldn't you want to pull it MORE than the others?" + next_section_and_step: "waste:understand_regret" + + - section_id: "epsilon_greedy" + title: "The Epsilon-Greedy Algorithm" + steps: + - step_id: "introduce_algorithm" + title: "Introducing Epsilon-Greedy" + content_blocks: + - "# 🎯 The Epsilon-Greedy Algorithm" + - "" + - "Now for the smart approach: **Epsilon-Greedy**" + - "" + - "**The algorithm:**" + - "1. Keep track of each machine's estimated win rate" + - "2. With probability **ε** (epsilon): EXPLORE (random machine)" + - "3. With probability **1-ε**: EXPLOIT (best machine so far)" + - "4. Update estimates after each pull" + - "" + - "**Example with ε = 0.1 (10% exploration):**" + - "- 10% of the time: Try a random machine (exploration)" + - "- 90% of the time: Pull the best machine you've found (exploitation)" + - "" + - "**Why this works:**" + - "- Early on: All estimates are uncertain, exploration finds the best" + - "- Later on: Estimates are good, exploitation maximizes reward" + - "- Always a small chance to explore (in case estimates are wrong)" + - "" + - "**Key data structures:**" + - "- Array of pull counts: [0, 0, 0]" + - "- Array of win counts: [0, 0, 0]" + - "- Array of win rates: [0.0, 0.0, 0.0]" + - "" + - "**After each pull:**" + - "- Increment pull count for that machine" + - "- If win: increment win count" + - "- Update win rate = wins / pulls" + + - step_id: "implement_epsilon_greedy" + title: "Implement Epsilon-Greedy" + question: | + Implement the epsilon-greedy algorithm! + + Requirements: + - 3 machines with true win rates: [0.3, 0.5, 0.2] + - 100 total pulls + - Epsilon = 0.1 (10% exploration) + - Track: pull counts, win counts, estimated win rates + - For each pull: + * Random number < 0.1? Explore (random machine) + * Otherwise: Exploit (best machine so far) + * Simulate the pull (win or lose based on true rate) + * Update statistics + - Print estimated win rates and total reward + + Focus on the logic - don't worry about perfect code! + tokens_for_ai: | + The student is implementing epsilon-greedy in their chosen language (metadata.programming_language). + + Check if their code includes: + - Arrays/lists for tracking (pull counts, wins, rates) + - Random number generation for epsilon decision AND pull simulation + - Exploration: pick random machine + - Exploitation: pick machine with highest estimated rate (handle ties) + - Update logic: increment counts, recalculate rates + - Loop for 100 pulls + + Categorize as 'excellent' if implementation is complete and correct. + Categorize as 'good_attempt' if logic is mostly right but has issues. + Categorize as 'needs_help' if they're struggling with the algorithm. + Categorize as 'set_language' if requesting language change. + Categorize as 'wrong_language' if using different language than metadata. + feedback_tokens_for_ai: | + Provide feedback in their chosen language: {metadata.programming_language} + + If excellent: CELEBRATE! 🎉 This is a real machine learning algorithm! + - Explain what should happen: After ~20 pulls, Machine B dominates + - Most pulls go to Machine B (the 50% winner) + - Occasional exploration keeps checking others + - Total reward is MUCH higher than A/B testing + - Regret is MUCH lower + - Provide their code with enthusiastic comments + + If good_attempt: + - Praise what works + - Fix specific issues (epsilon logic, argmax, update calculations) + - Provide corrected code + + If needs_help: + - Provide complete working implementation with detailed comments + - Explain the epsilon decision (random < 0.1) + - Explain argmax (finding best machine) + - Explain update logic (running average) + + If wrong_language: Remind them of their chosen language, provide correct version. + buckets: [excellent, good_attempt, needs_help, set_language, wrong_language] + transitions: + excellent: + ai_feedback: + tokens_for_ai: "Use feedback_tokens_for_ai instructions for excellent case" + metadata_add: + epsilon_greedy_completed: "true" + next_section_and_step: "comparison:compare_algorithms" + good_attempt: + ai_feedback: + tokens_for_ai: "Use feedback_tokens_for_ai instructions for good_attempt case" + metadata_add: + epsilon_greedy_completed: "true" + next_section_and_step: "comparison:compare_algorithms" + needs_help: + ai_feedback: + tokens_for_ai: "Use feedback_tokens_for_ai instructions for needs_help case" + counts_as_attempt: false + next_section_and_step: "epsilon_greedy:implement_epsilon_greedy" + set_language: + metadata_add: + language: "the-users-response" + content_blocks: + - "Language preference updated." + counts_as_attempt: false + next_section_and_step: "epsilon_greedy:implement_epsilon_greedy" + wrong_language: + ai_feedback: + tokens_for_ai: "Use feedback_tokens_for_ai instructions for wrong_language case" + counts_as_attempt: false + next_section_and_step: "epsilon_greedy:implement_epsilon_greedy" + + - section_id: "comparison" + title: "A/B vs Bandit Comparison" + steps: + - step_id: "compare_algorithms" + title: "The Dramatic Difference" + content_blocks: + - "# 📊 A/B Testing vs Epsilon-Greedy: The Results" + - "" + - "Let's compare what happens with 100 pulls:" + - "" + - "## 🐌 Traditional A/B Testing:" + - "- Machine A (30%): 33 pulls → ~10 wins" + - "- Machine B (50%): 33 pulls → ~16 wins" + - "- Machine C (20%): 34 pulls → ~7 wins" + - "- **Total wins: ~33**" + - "- **Total reward: -34** (you lose money!)" + - "- **Cumulative regret: ~17** (missed wins from not choosing B)" + - "" + - "## 🚀 Epsilon-Greedy (ε=0.1):" + - "- Machine A (30%): ~5 pulls → ~2 wins" + - "- Machine B (50%): ~90 pulls → ~45 wins" + - "- Machine C (20%): ~5 pulls → ~1 win" + - "- **Total wins: ~48**" + - "- **Total reward: -4** (much better!)" + - "- **Cumulative regret: ~2** (way lower!)" + - "" + - "**The difference:**" + - "- Epsilon-greedy wins **45% more** (15 extra wins)" + - "- Epsilon-greedy saves **30 wasted pulls**" + - "- Epsilon-greedy achieves **~88% lower regret**" + - "" + - "**This is why companies like Google, Facebook, and Amazon use bandit algorithms instead of A/B tests!**" + + - step_id: "tuning_epsilon" + title: "Understanding Epsilon" + question: "What do you think would happen if we set epsilon to 0.5 (50% exploration) instead of 0.1? Would it be better or worse?" + tokens_for_ai: | + Check if student understands the exploration/exploitation tradeoff. + + Higher epsilon = more exploration = MORE waste on bad arms. + The sweet spot is usually 0.01 to 0.2 depending on uncertainty. + + Categorize as 'correct' if they say worse/more regret/more waste/less focused. + Categorize as 'set_language' for language changes. + Categorize as 'incorrect' if they think higher epsilon is better. + buckets: [correct, set_language, incorrect] + transitions: + correct: + ai_feedback: + tokens_for_ai: | + Excellent insight! 🎯 + Explain: Higher epsilon = more random exploration = wasting pulls on known-bad arms. + Low epsilon (0.01-0.1) = mostly exploit the best, occasionally explore. + Connect to real-world: Early in a campaign, use higher epsilon (more uncertainty). + Later, use lower epsilon (you're confident about the best option). + Some algorithms even DECREASE epsilon over time! + next_section_and_step: "comparison:real_world" + set_language: + metadata_add: + language: "the-users-response" + content_blocks: + - "Language preference updated." + counts_as_attempt: false + next_section_and_step: "comparison:tuning_epsilon" + incorrect: + content_blocks: + - "**Think about it:**" + - "" + - "Epsilon = 0.5 means 50% of pulls are RANDOM." + - "Even after you know Machine B is best, half your pulls are wasted on A and C!" + - "" + - "Lower epsilon = more exploitation of the best option." + - "Higher epsilon = more exploration (useful only when very uncertain)." + next_section_and_step: "comparison:tuning_epsilon" + + - step_id: "real_world" + title: "Real-World Applications" + content_blocks: + - "# 🌍 Real-World Multi-Armed Bandits" + - "" + - "Companies use bandit algorithms every day:" + - "" + - "## 📱 Website Optimization" + - "**Problem:** Which button color converts better?" + - "**A/B test:** Show red to 50%, blue to 50% for 2 weeks" + - "**Bandit:** Start equal, shift traffic to winner within days" + - "**Result:** 30-50% more conversions during the test period" + - "" + - "## 📰 News Headline Testing" + - "**Problem:** Which headline gets more clicks?" + - "**Bandit:** Show all headlines initially, quickly focus on winners" + - "**Result:** Maximize engagement while learning" + - "" + - "## 💊 Clinical Trials" + - "**Problem:** Which treatment works better?" + - "**A/B test:** Give treatment A to 50%, treatment B to 50%" + - "**Bandit:** Shift MORE patients to effective treatment as you learn" + - "**Result:** More lives saved during the trial (ethical win!)" + - "" + - "## 🎯 Ad Placement" + - "**Problem:** Which ad creative performs best?" + - "**Bandit:** Automatically shift budget to high-performing ads" + - "**Result:** Lower cost per conversion, higher ROI" + - "" + - "## 🎮 Game Design" + - "**Problem:** Which difficulty level keeps players engaged?" + - "**Bandit:** Adapt difficulty to maximize playtime" + - "**Result:** Better player retention" + - "" + - "**Advanced algorithms:**" + - "- **Thompson Sampling:** Bayesian approach, often better than epsilon-greedy" + - "- **UCB (Upper Confidence Bound):** Uses confidence intervals" + - "- **Contextual Bandits:** Different arms for different user types" + - "- **Bayesian Bandits:** Full probability distributions" + + - section_id: "conclusion" + title: "Conclusion" + steps: + - step_id: "reflection" + title: "Final Reflection" + question: "In your own words, explain when you would use a bandit algorithm instead of traditional A/B testing, and why." + tokens_for_ai: | + Student should understand: + - Use bandits when you want to minimize regret (wasted resources) + - Use bandits when you can't afford to waste on losing options + - Use bandits when you want faster optimization + - A/B testing is simpler but wastes resources + + Categorize as 'excellent' if they clearly explain the efficiency/regret benefit. + Categorize as 'good' if they show understanding but less detailed. + Categorize as 'set_language' for language changes. + Categorize as 'needs_help' if they don't get the key benefit. + buckets: [excellent, good, set_language, needs_help] + transitions: + excellent: + ai_feedback: + tokens_for_ai: | + Celebrate their mastery! 🎉🎰 + They now understand a fundamental machine learning algorithm. + Highlight specific insights from their answer. + Encourage them to implement this in real projects. + Mention: This is just the beginning - Thompson Sampling, UCB, contextual bandits are even more powerful! + metadata_add: + activity_completed: "true" + mastery_level: "excellent" + next_section_and_step: "conclusion:goodbye" + good: + ai_feedback: + tokens_for_ai: | + Praise their understanding! + Emphasize the key point: Bandits minimize regret by adapting. + Encourage them to explore more advanced algorithms. + metadata_add: + activity_completed: "true" + mastery_level: "good" + next_section_and_step: "conclusion:goodbye" + set_language: + metadata_add: + language: "the-users-response" + content_blocks: + - "Language preference updated." + counts_as_attempt: false + next_section_and_step: "conclusion:reflection" + needs_help: + content_blocks: + - "**Key insight:**" + - "" + - "Bandit algorithms ADAPT as they learn." + - "A/B testing DOESN'T adapt - it keeps wasting resources on losing options." + - "" + - "**Use bandits when:**" + - "- You can't afford to waste resources (money, users, medical treatments)" + - "- You want to optimize faster" + - "- You want to minimize regret" + - "" + - "Give it another shot! When would you use a bandit algorithm?" + next_section_and_step: "conclusion:reflection" + + - step_id: "goodbye" + title: "Congratulations!" + content_blocks: + - "# 🎰🎉 Congratulations! You've Mastered Multi-Armed Bandits! 🎉🎰" + - "" + - "You now understand:" + - "✅ The exploration vs exploitation tradeoff" + - "✅ Why traditional A/B testing is wasteful" + - "✅ How epsilon-greedy minimizes regret" + - "✅ Real-world applications of bandit algorithms" + - "✅ How to implement adaptive learning in code" + - "" + - "**Next steps:**" + - "- Implement Thompson Sampling (Bayesian approach)" + - "- Learn UCB (Upper Confidence Bound) algorithm" + - "- Explore contextual bandits (different arms for different contexts)" + - "- Apply this to a real A/B testing scenario" + - "" + - "**You're now equipped with a powerful ML algorithm used by Google, Facebook, Amazon, and Netflix!**" + - "" + - "Keep exploring, keep exploiting! 🚀" diff --git a/research/activity50-genetic-algorithms.yaml b/research/activity50-genetic-algorithms.yaml new file mode 100644 index 0000000..3a171f8 --- /dev/null +++ b/research/activity50-genetic-algorithms.yaml @@ -0,0 +1,861 @@ +default_max_attempts_per_step: 3 +classifier_model: "MODEL_1" +feedback_model: "MODEL_1" + +tokens_for_ai_rubric: | + You are an enthusiastic evolution scientist teaching genetic algorithms! 🧬 + + Use the evolution metaphor throughout - "breeding," "survival of the fittest," "mutations." + Be encouraging and celebrate when students grasp concepts. + + The user's programming language is stored in metadata.programming_language (if set). + Always provide feedback in their chosen language. + + When evaluating code: + - Check if it implements the core concept (not perfect syntax) + - Look for understanding of: fitness, selection, crossover, mutation + - Praise creative approaches + - Guide gently if they're struggling + +sections: + - section_id: "introduction" + title: "Welcome to Genetic Algorithms" + steps: + - step_id: "welcome" + title: "Welcome" + content_blocks: + - "# 🧬 Welcome to Genetic Algorithms: Evolution in Code! 🧬" + - "" + - "Ever wondered how nature solves complex optimization problems?" + - "" + - "**Nature's secret**: Evolution! 🌱➡️🌳" + - "" + - "- **Reproduce** the best solutions" + - "- **Combine** traits from parents (crossover)" + - "- **Mutate** randomly for diversity" + - "- **Repeat** for many generations" + - "" + - "Today, you'll build a genetic algorithm that evolves solutions to problems that would take billions of years to solve by brute force!" + - "" + - "Let's start by choosing your programming language..." + + - step_id: "choose_language" + title: "Choose Programming Language" + question: "What programming language would you like to use? (Python, JavaScript, Java, C++, Ruby, Go, Rust, or any language you prefer)" + tokens_for_ai: | + Extract the programming language from their response. + Accept ANY language they mention: Python, JavaScript, Java, C++, C#, Ruby, Go, Rust, PHP, Swift, Kotlin, R, etc. + + Categorize as 'language_chosen' if they name a specific language. + Categorize as 'unsure' if they seem uncertain or ask for a recommendation. + Categorize as 'off_topic' if completely unrelated. + buckets: [language_chosen, unsure, off_topic, set_language] + transitions: + language_chosen: + metadata_add: + programming_language: "the-users-response" + ai_feedback: + tokens_for_ai: | + Great choice! Celebrate their language selection. + Mention one reason why their language is good for genetic algorithms. + (e.g., Python has great list operations, JavaScript has functional programming, etc.) + next_section_and_step: "concepts:evolution_metaphor" + unsure: + content_blocks: + - "No worries! 😊" + - "" + - "**I recommend Python** for beginners - it's clear and readable." + - "**JavaScript** is great if you're web-focused." + - "**C++** or **Rust** if you want performance." + - "" + - "Pick whichever you're most comfortable with - genetic algorithms work in ANY language!" + counts_as_attempt: false + next_section_and_step: "introduction:choose_language" + off_topic: + content_blocks: + - "Let's focus on choosing a programming language first! 🎯" + - "" + - "Popular choices: Python, JavaScript, Java, C++, Ruby, Go, Rust" + - "" + - "Which language would you like to use?" + counts_as_attempt: false + next_section_and_step: "introduction:choose_language" + set_language: + content_blocks: + - "Language preference updated! 🌍" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: "introduction:choose_language" + + - section_id: "concepts" + title: "Understanding Genetic Algorithms" + steps: + - step_id: "evolution_metaphor" + title: "The Evolution Metaphor" + content_blocks: + - "# 🦎 How Evolution Solves Complex Problems 🦎" + - "" + - "Imagine you want to find the **perfect solution** to a problem." + - "" + - "**Brute Force**: Try every possibility ❌" + - "- Problem: 10 variables, 100 values each = 100^10 = 100 trillion trillion possibilities!" + - "- Would take longer than the age of the universe 🌌" + - "" + - "**Genetic Algorithm**: Let solutions evolve ✅" + - "- Start with random guesses (generation 1)" + - "- Keep the best ones" + - "- Breed them together (crossover)" + - "- Add random mutations" + - "- Repeat for 100 generations" + - "- Find excellent solutions in seconds! ⚡" + - "" + - "This is how nature designed complex organisms over millions of years." + - "We'll do it in code in minutes! 🧬" + + - step_id: "ga_components" + title: "Genetic Algorithm Components" + content_blocks: + - "# 🧬 The 5 Core Components of Genetic Algorithms" + - "" + - "## 1️⃣ **Population** (Pool of Candidates)" + - "- A collection of potential solutions" + - "- Each solution is called a **chromosome**" + - "- Example: Random strings trying to match \"GENETIC\"" + - "" + - "## 2️⃣ **Fitness Function** (Survival Test)" + - "- Measures how good each solution is" + - "- Better fitness = more likely to survive" + - "- Example: Count matching letters in the string" + - "" + - "## 3️⃣ **Selection** (Choose the Best)" + - "- Pick the fittest individuals to reproduce" + - "- Methods: Tournament, Roulette Wheel, Elite Selection" + - "- Survival of the fittest! 💪" + - "" + - "## 4️⃣ **Crossover** (Breeding)" + - "- Combine two parent solutions" + - "- Create offspring with mixed traits" + - "- Example: \"GEN\" + \"TIC\" = \"GENIC\"" + - "" + - "## 5️⃣ **Mutation** (Random Changes)" + - "- Randomly modify some offspring" + - "- Prevents getting stuck in local optima" + - "- Adds diversity to the gene pool 🌈" + + - step_id: "understand_components" + title: "Check Understanding" + question: "In your own words, why do we need BOTH crossover AND mutation in genetic algorithms? (Hint: Think about what each one does for the solution space)" + tokens_for_ai: | + Categorize their understanding: + + 'deep_understanding' if they mention BOTH: + - Crossover combines good traits from parents (exploitation) + - Mutation explores new possibilities and prevents premature convergence (exploration) + + 'partial_understanding' if they mention ONE of: + - Crossover combines solutions + - Mutation adds randomness/diversity + + 'creative_thinking' if wrong but shows good reasoning about evolution/optimization + + 'needs_help' if confused or very brief + + 'set_language' if changing language preference + + 'off_topic' otherwise + feedback_tokens_for_ai: | + Provide feedback in their chosen language from metadata.programming_language. + + If deep_understanding: Celebrate! Explain this is the exploration-exploitation tradeoff. + If partial_understanding: Acknowledge what they got right, add the missing piece. + If creative_thinking: Appreciate their reasoning, gently guide to the core concept. + If needs_help: Use an analogy - crossover is like breeding dogs (mix best traits), mutation is like genetic mutations (new random traits). + buckets: [deep_understanding, partial_understanding, creative_thinking, needs_help, set_language, off_topic] + transitions: + deep_understanding: + ai_feedback: + tokens_for_ai: "Celebrate their understanding! Mention the exploration-exploitation tradeoff is key to many optimization algorithms." + next_section_and_step: "problem:define_problem" + partial_understanding: + ai_feedback: + tokens_for_ai: "Acknowledge what they got right. Explain the missing piece (exploration vs exploitation). Be encouraging!" + next_section_and_step: "problem:define_problem" + creative_thinking: + ai_feedback: + tokens_for_ai: "Appreciate their creative thinking! Guide them to the core: crossover=exploit good solutions, mutation=explore new ones." + next_section_and_step: "problem:define_problem" + needs_help: + content_blocks: + - "Let me clarify! 🎯" + - "" + - "**Crossover** = Combine the BEST traits from parents" + - "- Focuses on what's already working" + - "- Exploitation of good solutions" + - "" + - "**Mutation** = Random changes" + - "- Explores NEW possibilities" + - "- Prevents getting stuck" + - "" + - "**Together** = Perfect balance of using what works + trying new things! 🧬" + next_section_and_step: "problem:define_problem" + set_language: + content_blocks: + - "Language preference updated! 🌍" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: "concepts:understand_components" + off_topic: + content_blocks: + - "Let's stay focused on genetic algorithms! 🧬" + - "" + - "Think about why we need BOTH crossover (combining solutions) AND mutation (random changes)." + counts_as_attempt: false + next_section_and_step: "concepts:understand_components" + + - section_id: "problem" + title: "Define the Problem" + steps: + - step_id: "define_problem" + title: "Our Evolution Challenge" + content_blocks: + - "# 🎯 The String Evolution Challenge" + - "" + - "**Goal**: Evolve random characters into the string \"GENETIC\"" + - "" + - "**Starting Point**:" + - "- Population of 100 random 7-letter strings" + - "- Example: \"XQMZPRL\", \"KDJFHGA\", \"BVNCXZM\"" + - "- Fitness = 0 (no matching letters)" + - "" + - "**After 100 Generations**:" + - "- Best solution: \"GENETIC\"" + - "- Fitness = 7 (perfect match!)" + - "- We'll watch evolution happen! 🧬➡️✨" + - "" + - "**Why This Problem?**" + - "- Easy to understand fitness (count matching letters)" + - "- Brute force: 26^7 = 8 billion possibilities" + - "- GA solves it in ~100 generations with population of 100 = 10,000 evaluations" + - "- **800,000x faster than brute force!** ⚡" + - "" + - "Let's build it step by step..." + + - section_id: "implementation" + title: "Build the Genetic Algorithm" + steps: + - step_id: "fitness_function" + title: "Step 1: Fitness Function" + question: "Write a fitness function that takes a candidate string and returns how many letters match \"GENETIC\" in the correct positions. Think about how you'd measure similarity!" + tokens_for_ai: | + Evaluate their fitness function code in their chosen language (metadata.programming_language). + + 'excellent_implementation' if they: + - Compare each character position + - Count matches + - Handle string comparison correctly + - Code looks reasonable (don't nitpick syntax) + + 'correct_concept' if they describe the approach correctly even if code has minor issues + + 'partial_understanding' if they count total matching letters but not position-specific + + 'needs_guidance' if confused or very incomplete + + 'set_language' if changing language + + 'off_topic' otherwise + feedback_tokens_for_ai: | + Provide feedback in their language (metadata.programming_language). + + If excellent_implementation: + - Celebrate! Show how this fitness function guides evolution. + - Mention: "This is the KEY - fitness drives everything!" + + If correct_concept or partial_understanding: + - Acknowledge their understanding + - If not position-specific, explain why positions matter + - Show a working example of the fitness function + + If needs_guidance: + - Provide a complete working example + - Explain: loop through each position, count matches + - Walk through: "GXXXXXX" vs "GENETIC" = fitness of 1 + buckets: [excellent_implementation, correct_concept, partial_understanding, needs_guidance, set_language, off_topic] + transitions: + excellent_implementation: + ai_feedback: + tokens_for_ai: "Celebrate! Show example: fitness('GXXXXXX') = 1, fitness('GENETIC') = 7. Mention this guides ALL evolution!" + metadata_add: + fitness_complete: "true" + progress_score: "1" + next_section_and_step: "implementation:selection" + correct_concept: + ai_feedback: + tokens_for_ai: "Great concept! Show a polished working version in their language. Explain how it works step-by-step." + metadata_add: + fitness_complete: "true" + progress_score: "1" + next_section_and_step: "implementation:selection" + partial_understanding: + ai_feedback: + tokens_for_ai: "Good start! Explain why POSITION matters. Show corrected version comparing index-by-index." + metadata_add: + fitness_complete: "true" + progress_score: "1" + next_section_and_step: "implementation:selection" + needs_guidance: + ai_feedback: + tokens_for_ai: "No worries! Provide complete working fitness function in their language. Walk through example: 'GXXXXXX' scores 1 because only first 'G' matches." + metadata_add: + fitness_complete: "true" + progress_score: "1" + next_section_and_step: "implementation:selection" + set_language: + content_blocks: + - "Language preference updated! 🌍" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: "implementation:fitness_function" + off_topic: + content_blocks: + - "Let's focus on the fitness function! 🎯" + - "" + - "Your task: Write code that counts how many letters in a candidate string match \"GENETIC\" at the same positions." + - "" + - "Example: \"GXXXXXX\" should return 1 (only the G matches)" + counts_as_attempt: false + next_section_and_step: "implementation:fitness_function" + + - step_id: "selection" + title: "Step 2: Selection (Choose the Fittest)" + question: "Write a selection function that picks the best individuals from the population. Describe your strategy: will you use tournament selection (pick best from random groups), elite selection (just take the top N), or another method?" + tokens_for_ai: | + Evaluate their selection implementation/strategy. + + 'excellent_implementation' if they: + - Describe a valid selection method (tournament, elite, roulette wheel, etc.) + - Show code or clear algorithm + - Understand it favors higher fitness + + 'correct_strategy' if they describe a valid approach even without perfect code + + 'creative_approach' if they invent a reasonable selection method + + 'needs_guidance' if confused or missing the "favor fitness" concept + + 'set_language' if changing language + + 'off_topic' otherwise + feedback_tokens_for_ai: | + Provide feedback in their language (metadata.programming_language). + + If excellent_implementation: + - Praise their approach! + - Explain why their method works (survival of fittest) + - Show example: population of 100 → select top 50 for breeding + + If correct_strategy or creative_approach: + - Validate their thinking + - Show a clean implementation + - Mention: "Selection pressure drives evolution!" + + If needs_guidance: + - Explain selection favors fit individuals + - Provide tournament selection example: pick 5 random, take the best, repeat + - Or elite selection: sort by fitness, take top 50% + buckets: [excellent_implementation, correct_strategy, creative_approach, needs_guidance, set_language, off_topic] + transitions: + excellent_implementation: + ai_feedback: + tokens_for_ai: "Fantastic! Explain how their selection method creates selection pressure. Show example with fitnesses [7,5,3,1] → likely picks 7 and 5." + metadata_add: + selection_complete: "true" + progress_score: "n+1" + next_section_and_step: "implementation:crossover" + correct_strategy: + ai_feedback: + tokens_for_ai: "Great strategy! Polish their idea with clean code example. Emphasize: this is survival of the fittest in action! 💪" + metadata_add: + selection_complete: "true" + progress_score: "n+1" + next_section_and_step: "implementation:crossover" + creative_approach: + ai_feedback: + tokens_for_ai: "Love the creativity! Validate if their method favors fitness. Show how it compares to standard approaches." + metadata_add: + selection_complete: "true" + progress_score: "n+1" + next_section_and_step: "implementation:crossover" + needs_guidance: + ai_feedback: + tokens_for_ai: "Let me help! Explain tournament selection: randomly pick 5 individuals, select the fittest, repeat. Show complete code example in their language." + metadata_add: + selection_complete: "true" + progress_score: "n+1" + next_section_and_step: "implementation:crossover" + set_language: + content_blocks: + - "Language preference updated! 🌍" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: "implementation:selection" + off_topic: + content_blocks: + - "Let's focus on selection! 🎯" + - "" + - "**Goal**: Pick the best individuals to be parents" + - "" + - "Think about: How do you favor high-fitness individuals while still allowing some diversity?" + counts_as_attempt: false + next_section_and_step: "implementation:selection" + + - step_id: "crossover" + title: "Step 3: Crossover (Breeding)" + question: "Write a crossover function that takes two parent strings and creates offspring by combining their genes. How will you mix the parents' traits?" + tokens_for_ai: | + Evaluate their crossover implementation. + + 'excellent_implementation' if they: + - Show code that combines two parent strings + - Use any valid method (single-point, two-point, uniform) + - Create offspring with mixed traits + + 'correct_concept' if they describe crossover correctly even with imperfect code + + 'creative_approach' if they invent a reasonable mixing strategy + + 'needs_guidance' if confused or doesn't mix parent traits + + 'set_language' if changing language + + 'off_topic' otherwise + feedback_tokens_for_ai: | + Provide feedback in their language (metadata.programming_language). + + If excellent_implementation: + - Celebrate! Show their crossover in action + - Example: parent1="GENXXXX", parent2="XXXETIC" → child="GENETIC" (if lucky!) + - Explain: "This is how good traits combine! 🧬" + + If correct_concept or creative_approach: + - Validate their approach + - Show polished implementation + - Demo with example parents + + If needs_guidance: + - Explain single-point crossover + - Example: "GEN|XXXX" + "XXX|ETIC" → "GENETIC" + - Provide complete code in their language + buckets: [excellent_implementation, correct_concept, creative_approach, needs_guidance, set_language, off_topic] + transitions: + excellent_implementation: + ai_feedback: + tokens_for_ai: "Perfect! Show their crossover creating offspring. Example: 'GENXXXX' + 'XXXETIC' → 'GENETIC'. This is evolution magic! ✨" + metadata_add: + crossover_complete: "true" + progress_score: "n+1" + next_section_and_step: "implementation:mutation" + correct_concept: + ai_feedback: + tokens_for_ai: "Great concept! Show refined code. Demo with concrete parent strings. Emphasize: this exploits existing good genes! 🧬" + metadata_add: + crossover_complete: "true" + progress_score: "n+1" + next_section_and_step: "implementation:mutation" + creative_approach: + ai_feedback: + tokens_for_ai: "Interesting approach! Validate if it mixes parent traits. Compare to standard single-point crossover." + metadata_add: + crossover_complete: "true" + progress_score: "n+1" + next_section_and_step: "implementation:mutation" + needs_guidance: + ai_feedback: + tokens_for_ai: "Let me show you! Explain single-point crossover with diagram. Provide complete working code in their language." + metadata_add: + crossover_complete: "true" + progress_score: "n+1" + next_section_and_step: "implementation:mutation" + set_language: + content_blocks: + - "Language preference updated! 🌍" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: "implementation:crossover" + off_topic: + content_blocks: + - "Let's focus on crossover! 🧬" + - "" + - "**Goal**: Combine two parent strings to create offspring" + - "" + - "Think about: How do you mix traits from both parents into a child?" + - "One approach: Take first half from parent1, second half from parent2" + counts_as_attempt: false + next_section_and_step: "implementation:crossover" + + - step_id: "mutation" + title: "Step 4: Mutation (Random Changes)" + question: "Write a mutation function that randomly changes some characters in a string with small probability (like 1% per character). How will you add this random diversity?" + tokens_for_ai: | + Evaluate their mutation implementation. + + 'excellent_implementation' if they: + - Show code that randomly modifies characters + - Use low probability (1-10%) + - Replace with random letters + + 'correct_concept' if they describe mutation correctly even with imperfect code + + 'creative_approach' if they use an alternative randomization strategy + + 'needs_guidance' if confused or mutates too much/little + + 'set_language' if changing language + + 'off_topic' otherwise + feedback_tokens_for_ai: | + Provide feedback in their language (metadata.programming_language). + + If excellent_implementation: + - Praise! Show mutation in action + - Example: "GENETIC" → "GENXTIC" (small random change) + - Explain: "Prevents getting stuck! Explores new possibilities! 🌈" + + If correct_concept or creative_approach: + - Validate their understanding + - Show clean implementation with proper probability + - Demo: mutate 'GENETIC' a few times + + If needs_guidance: + - Explain: loop through characters, 1% chance each mutates to random letter + - Show complete code in their language + - Warn: too much mutation = random search, too little = stuck + buckets: [excellent_implementation, correct_concept, creative_approach, needs_guidance, set_language, off_topic] + transitions: + excellent_implementation: + ai_feedback: + tokens_for_ai: "Excellent! Demo their mutation. Explain: this is the spark of innovation in evolution! Small random changes = big discoveries. 🌈" + metadata_add: + mutation_complete: "true" + progress_score: "n+1" + next_section_and_step: "execution:main_loop" + correct_concept: + ai_feedback: + tokens_for_ai: "Great understanding! Show polished code with ~1% mutation rate. Demo mutating 'GENETIC' several times." + metadata_add: + mutation_complete: "true" + progress_score: "n+1" + next_section_and_step: "execution:main_loop" + creative_approach: + ai_feedback: + tokens_for_ai: "Creative! Validate their mutation strategy. Compare mutation rate to standard 1-5% per gene." + metadata_add: + mutation_complete: "true" + progress_score: "n+1" + next_section_and_step: "execution:main_loop" + needs_guidance: + ai_feedback: + tokens_for_ai: "Let me guide you! Explain: for each character, 1% chance to replace with random letter A-Z. Provide complete code in their language." + metadata_add: + mutation_complete: "true" + progress_score: "n+1" + next_section_and_step: "execution:main_loop" + set_language: + content_blocks: + - "Language preference updated! 🌍" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: "implementation:mutation" + off_topic: + content_blocks: + - "Let's focus on mutation! 🧬" + - "" + - "**Goal**: Randomly change some characters to add diversity" + - "" + - "Think about: For each character, maybe 1% chance to randomly change it to a different letter" + - "Why? Prevents getting stuck in local optima!" + counts_as_attempt: false + next_section_and_step: "implementation:mutation" + + - section_id: "execution" + title: "Run the Evolution!" + steps: + - step_id: "main_loop" + title: "Step 5: The Evolution Loop" + question: "Now write the main GA loop that ties everything together: (1) Create random population, (2) For each generation: evaluate fitness, select parents, crossover, mutate, (3) Repeat for 100 generations, (4) Print the best solution. Show me your implementation!" + tokens_for_ai: | + Evaluate their main GA loop implementation. + + 'complete_implementation' if they: + - Initialize random population + - Have generation loop + - Call fitness, selection, crossover, mutation + - Track/print best solution + + 'correct_structure' if they describe the algorithm correctly even with incomplete code + + 'partial_implementation' if missing some components but core loop is there + + 'needs_guidance' if confused or very incomplete + + 'set_language' if changing language + + 'off_topic' otherwise + feedback_tokens_for_ai: | + Provide feedback in their language (metadata.programming_language). + + If complete_implementation: + - CELEBRATE! They built a complete GA! 🎉 + - Show example output: + "Gen 1: Best='XQMZPRL' (fitness=0) + Gen 50: Best='GENXTIX' (fitness=5) + Gen 100: Best='GENETIC' (fitness=7) ✨" + - Explain: "You just implemented evolution in code!" + + If correct_structure or partial_implementation: + - Praise their understanding + - Show complete polished version + - Explain the flow: random → loop(fitness, select, breed, mutate) → evolved! + + If needs_guidance: + - Provide complete working GA code in their language + - Walk through: "This is the ENTIRE algorithm in ~50 lines!" + - Show sample output across generations + buckets: [complete_implementation, correct_structure, partial_implementation, needs_guidance, set_language, off_topic] + transitions: + complete_implementation: + ai_feedback: + tokens_for_ai: "AMAZING! 🎉 They built a complete genetic algorithm! Show example output with fitness improving over generations. Celebrate: 'You implemented EVOLUTION!' 🧬✨" + metadata_add: + ga_complete: "true" + progress_score: "n+1" + implementation_quality: "complete" + next_section_and_step: "execution:observe_evolution" + correct_structure: + ai_feedback: + tokens_for_ai: "Great structure! Show complete polished version with all components. Explain: this is the heart of evolutionary computation! 💚" + metadata_add: + ga_complete: "true" + progress_score: "n+1" + implementation_quality: "good" + next_section_and_step: "execution:observe_evolution" + partial_implementation: + ai_feedback: + tokens_for_ai: "Good start! Fill in missing pieces. Show complete working version. Emphasize: all the parts work together like an ecosystem! 🌱" + metadata_add: + ga_complete: "true" + progress_score: "n+1" + implementation_quality: "partial" + next_section_and_step: "execution:observe_evolution" + needs_guidance: + ai_feedback: + tokens_for_ai: "Let me show the complete algorithm! Provide full working GA code in their language (~50 lines). Walk through the flow. Show example output." + metadata_add: + ga_complete: "true" + progress_score: "n+1" + implementation_quality: "guided" + next_section_and_step: "execution:observe_evolution" + set_language: + content_blocks: + - "Language preference updated! 🌍" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: "execution:main_loop" + off_topic: + content_blocks: + - "Let's focus on the main evolution loop! 🔄" + - "" + - "You need to:" + - "1. Create random population" + - "2. Loop for 100 generations:" + - " - Calculate fitness for all" + - " - Select best individuals" + - " - Create offspring via crossover" + - " - Mutate offspring" + - " - Replace old population" + - "3. Print the best solution found" + counts_as_attempt: false + next_section_and_step: "execution:main_loop" + + - step_id: "observe_evolution" + title: "Observe Evolution in Action" + content_blocks: + - "# 🔬 Watch Evolution Happen! 🔬" + - "" + - "If you ran your genetic algorithm, you'd see something AMAZING:" + - "" + - "```" + - "Generation 1: Best='XQMZPRL' Fitness=0 😕" + - "Generation 10: Best='GXXXXXX' Fitness=1 🌱" + - "Generation 25: Best='GENXXXX' Fitness=3 🌿" + - "Generation 50: Best='GENXTIX' Fitness=5 🌳" + - "Generation 75: Best='GENETIX' Fitness=6 🌲" + - "Generation 100: Best='GENETIC' Fitness=7 ✨🎉" + - "```" + - "" + - "**What just happened?**" + - "- Started with pure randomness" + - "- Each generation got BETTER" + - "- Good genes survived and spread" + - "- Mutations found missing letters" + - "- **EVOLUTION WORKED!** 🧬" + - "" + - "**The Math**:" + - "- Brute force: 26^7 = 8,031,810,176 tries" + - "- GA: 100 generations × 100 population = 10,000 tries" + - "- **803,181x faster!** ⚡⚡⚡" + - "" + - "This is the power of evolutionary algorithms! 💪" + + - step_id: "when_to_use" + title: "When to Use Genetic Algorithms" + question: "Based on what you learned, when would you use a genetic algorithm versus other optimization methods? Think about problem characteristics that make GAs shine! 🤔" + tokens_for_ai: | + Evaluate their understanding of when GAs are appropriate. + + 'excellent_insight' if they mention 2+ of: + - Large search spaces (can't brute force) + - No clear gradient/derivative (can't use gradient descent) + - Multiple local optima (need exploration) + - Complex fitness landscapes + - Combinatorial optimization + - Don't need perfect solution, just good enough + + 'good_understanding' if they mention 1 key insight about search space or optimization landscape + + 'partial_understanding' if they understand GAs are for hard problems but vague on details + + 'needs_clarification' if confused or missing the key concepts + + 'set_language' if changing language + + 'off_topic' otherwise + feedback_tokens_for_ai: | + Provide feedback in their language (metadata.programming_language). + + If excellent_insight: + - CELEBRATE their deep understanding! 🎉 + - Mention real applications: scheduling, circuit design, game AI, neural architecture search + - Note: GAs are part of evolutionary computation family + + If good_understanding or partial_understanding: + - Validate what they got right + - Add missing pieces: + * HUGE search spaces (can't enumerate) + * Non-differentiable (can't gradient descent) + * Multiple peaks (need exploration) + - Give examples: TSP, job scheduling, game balancing + + If needs_clarification: + - Explain: GAs excel when: + * Search space is enormous + * No gradient available + * Many local optima to escape + - Examples: routing problems, game AI, design optimization + buckets: [excellent_insight, good_understanding, partial_understanding, needs_clarification, set_language, off_topic] + transitions: + excellent_insight: + ai_feedback: + tokens_for_ai: "Outstanding! 🌟 List real applications: job scheduling, circuit design, game AI, neural architecture search, traveling salesman. They've mastered when to use GAs!" + metadata_add: + activity_completed: "true" + mastery_level: "excellent" + next_section_and_step: "conclusion:celebrate" + good_understanding: + ai_feedback: + tokens_for_ai: "Great insight! Add: GAs shine on huge search spaces, non-differentiable problems, multiple local optima. Give examples: TSP, scheduling, game AI." + metadata_add: + activity_completed: "true" + mastery_level: "good" + next_section_and_step: "conclusion:celebrate" + partial_understanding: + ai_feedback: + tokens_for_ai: "You're on the right track! Explain: GAs work when search space is huge, no gradient, many peaks. Examples: routing, scheduling, design optimization." + metadata_add: + activity_completed: "true" + mastery_level: "developing" + next_section_and_step: "conclusion:celebrate" + needs_clarification: + content_blocks: + - "Let me clarify when GAs are perfect! 🎯" + - "" + - "**Use Genetic Algorithms When:**" + - "" + - "✅ **Huge search space** (billions of possibilities)" + - "✅ **No gradient** (can't use calculus-based optimization)" + - "✅ **Many local optima** (need to explore, not just climb)" + - "✅ **Combinatorial** (scheduling, routing, packing)" + - "✅ **Good enough is enough** (don't need perfect solution)" + - "" + - "**Examples:**" + - "- Traveling Salesman Problem 🗺️" + - "- Job scheduling 📅" + - "- Game AI balancing ⚔️" + - "- Circuit design 🔌" + - "- Neural architecture search 🧠" + - "" + - "GAs explore intelligently without needing derivatives or exhaustive search!" + metadata_add: + activity_completed: "true" + mastery_level: "developing" + next_section_and_step: "conclusion:celebrate" + set_language: + content_blocks: + - "Language preference updated! 🌍" + metadata_add: + language: "the-users-response" + counts_as_attempt: false + next_section_and_step: "execution:when_to_use" + off_topic: + content_blocks: + - "Let's think about when GAs are the right tool! 🔧" + - "" + - "Consider: What types of problems would benefit from evolutionary search?" + - "" + - "Hints:" + - "- How big is the search space?" + - "- Can you calculate gradients?" + - "- Are there many local optima?" + counts_as_attempt: false + next_section_and_step: "execution:when_to_use" + + - section_id: "conclusion" + title: "Conclusion" + steps: + - step_id: "celebrate" + title: "Congratulations!" + content_blocks: + - "# 🎉 Congratulations, Evolution Architect! 🎉" + - "" + - "You just mastered genetic algorithms! Here's what you built:" + - "" + - "✅ **Fitness Function** - Measured solution quality" + - "✅ **Selection** - Survival of the fittest" + - "✅ **Crossover** - Breeding the best traits" + - "✅ **Mutation** - Exploring new possibilities" + - "✅ **Evolution Loop** - Bringing it all together" + - "" + - "**You learned:**" + - "- How nature solves complex optimization problems" + - "- Why evolution is an incredible search algorithm" + - "- When to use GAs vs other optimization methods" + - "- The exploration-exploitation tradeoff" + - "" + - "**Next Steps:**" + - "- Try more complex problems (TSP, knapsack, game AI)" + - "- Experiment with different selection/crossover strategies" + - "- Learn about: Genetic Programming, Evolution Strategies, Neuroevolution" + - "- Apply GAs to real optimization problems in your domain" + - "" + - "**Remember**: Evolution isn't just biology - it's a powerful computational paradigm! 🧬⚡" + - "" + - "Keep evolving your code! 🚀" + - "" + - "— Your Evolution Guide 🦎✨" diff --git a/research/activity51-connect-four.yaml b/research/activity51-connect-four.yaml new file mode 100644 index 0000000..1272499 --- /dev/null +++ b/research/activity51-connect-four.yaml @@ -0,0 +1,964 @@ +default_max_attempts_per_step: 3 +classifier_model: "MODEL_1" +feedback_model: "MODEL_1" + +tokens_for_ai_rubric: | + Evaluate the student's code and understanding based on: + - Does their code implement the required functionality? + - Is their logic sound, even if syntax has minor issues? + - Do they demonstrate understanding of the underlying concepts? + - For conceptual questions, do they explain the key ideas correctly? + + Be encouraging! They're building a real game from scratch. + Always reference their chosen programming language from metadata.programming_language. + +sections: + - section_id: "introduction" + title: "Welcome to Connect Four!" + steps: + - step_id: "welcome" + title: "Introduction" + content_blocks: + - "# 🎮 Build Your Own Connect Four Game!" + - "" + - "Connect Four is a classic two-player strategy game where players take turns dropping colored discs into a 7-column, 6-row grid." + - "" + - "**The Goal:** Connect four of your discs in a row - horizontally, vertically, or diagonally - before your opponent does!" + - "" + - "**What You'll Learn:**" + - "- 2D arrays and nested data structures" + - "- Game state management" + - "- Input validation" + - "- Algorithm design (win detection is surprisingly interesting!)" + - "- Modular code with functions" + - "" + - "By the end, you'll have a working Connect Four game you can play!" + + - section_id: "language_choice" + title: "Choose Your Programming Language" + steps: + - step_id: "choose_language" + title: "Language Selection" + question: "What programming language would you like to use? (Python, JavaScript, Java, C++, C, Ruby, Go, or any other language you prefer)" + tokens_for_ai: | + The student is selecting their programming language. + Store whatever language they choose in metadata.programming_language. + Categorize as 'language_selected' if they provide any programming language name. + Categorize as 'unclear' if their response is ambiguous or doesn't mention a language. + buckets: [language_selected, unclear] + transitions: + language_selected: + content_blocks: + - "Excellent choice! All code examples and feedback will be tailored to your language." + metadata_add: + programming_language: "the-users-response" + next_section_and_step: "board_representation:explain_board" + unclear: + content_blocks: + - "I didn't catch which language you'd like to use." + - "Please specify a programming language like Python, JavaScript, Java, C++, etc." + next_section_and_step: "language_choice:choose_language" + + - section_id: "board_representation" + title: "Step 1: Representing the Board" + steps: + - step_id: "explain_board" + title: "Board Data Structure" + content_blocks: + - "# 📊 Step 1: How Do We Represent the Board?" + - "" + - "Connect Four uses a 7-column by 6-row grid. We need a data structure to store:" + - "- Empty spaces" + - "- Player 1's pieces (let's use 'X')" + - "- Player 2's pieces (let's use 'O')" + - "" + - "**The Key Concept: 2D Arrays**" + - "" + - "A 2D array (or nested list) is like a grid - it has rows and columns. Think of it as a list of lists:" + - "- The outer list contains rows" + - "- Each inner list contains the columns for that row" + - "" + - "For Connect Four, we typically use 6 rows (index 0-5) and 7 columns (index 0-6)." + - "" + - "**Convention:** We'll index from top (row 0) to bottom (row 5), left (column 0) to right (column 6)." + + - step_id: "implement_board" + title: "Create the Board" + question: "Write code to create an empty Connect Four board (6 rows, 7 columns). Use a 2D array/list and fill it with empty spaces or a placeholder like '.' or ' '." + tokens_for_ai: | + Get the programming language from metadata.programming_language. + + The student should create a 2D array/list representing a 6x7 board. + + Categorize as 'excellent' if they: + - Create a 6x7 2D structure (rows x columns) + - Initialize all positions with empty markers + - Use appropriate syntax for their language + + Categorize as 'correct' if they: + - Create the right dimensions + - Minor syntax issues but concept is clear + + Categorize as 'wrong_dimensions' if they: + - Mix up rows/columns (7x6 instead of 6x7) + - But otherwise have the right idea + + Categorize as 'needs_guidance' if they: + - Don't understand 2D arrays + - Need help with the concept + + Categorize as 'set_language' if they want to switch languages. + feedback_tokens_for_ai: | + Provide feedback based on their code in metadata.programming_language. + + If excellent/correct: + - Praise their implementation + - Show them their code could be used to initialize: board = create_empty_board() + - Mention this is the foundation for everything else + + If wrong_dimensions: + - Gently correct: "Close! Remember, 6 ROWS (height) by 7 COLUMNS (width)" + - Explain the difference between board[row][col] indexing + + If needs_guidance: + - Show a SMALL example of a 2x3 board (not the full solution!) + - Explain nested lists/arrays conceptually + - Encourage them to try again + buckets: [excellent, correct, wrong_dimensions, needs_guidance, set_language] + transitions: + excellent: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + metadata_add: + board_created: "true" + progress_score: "1" + next_section_and_step: "display_board:explain_display" + correct: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + metadata_add: + board_created: "true" + progress_score: "1" + next_section_and_step: "display_board:explain_display" + wrong_dimensions: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + next_section_and_step: "board_representation:implement_board" + needs_guidance: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + next_section_and_step: "board_representation:implement_board" + set_language: + content_blocks: + - "Language preference updated!" + metadata_add: + programming_language: "the-users-response" + counts_as_attempt: false + next_section_and_step: "board_representation:implement_board" + + - section_id: "display_board" + title: "Step 2: Displaying the Board" + steps: + - step_id: "explain_display" + title: "Print the Board" + content_blocks: + - "# 🖨️ Step 2: Displaying the Board" + - "" + - "Great! You've created the data structure. Now we need to visualize it." + - "" + - "**The Challenge:** Turn your 2D array into a readable game board on screen." + - "" + - "**Concept: Nested Loops**" + - "- Outer loop: iterate through each row" + - "- Inner loop: iterate through each column in that row" + - "- Print each cell, then move to the next line after each row" + - "" + - "**Bonus Points:** Add column numbers (0-6) at the top or bottom to help players choose where to drop!" + + - step_id: "implement_display" + title: "Write Display Function" + question: "Write a function called display_board (or similar) that takes your board as a parameter and prints it in a readable format. Show each row and make it clear which positions are empty." + tokens_for_ai: | + Get the programming language from metadata.programming_language. + + The student should write a function that displays the board. + + Categorize as 'excellent' if they: + - Use nested loops correctly + - Print all rows and columns + - Make it readable (spacing, separators, column labels) + - Proper function syntax + + Categorize as 'correct' if they: + - Core logic is right (nested loops) + - Displays the board even if formatting is basic + - Function structure is correct + + Categorize as 'partial' if they: + - Have the concept but loops are wrong + - Or miss the function wrapper but logic exists + + Categorize as 'needs_help' if they're stuck on nested loops. + + Categorize as 'set_language' if switching languages. + feedback_tokens_for_ai: | + Provide feedback in metadata.programming_language. + + If excellent/correct: + - Celebrate: "Your board looks great! 🎨" + - Suggest enhancements like separators between cells: | or borders + - Note this function will be called after every move + + If partial: + - Identify what's working + - Guide them on the nested loop structure + - Explain outer loop = rows, inner loop = columns + + If needs_help: + - Explain nested loop concept clearly + - Give pseudocode (not full code): + for each row in board: + for each cell in row: + print cell + print newline + - Encourage them to try + buckets: [excellent, correct, partial, needs_help, set_language] + transitions: + excellent: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + metadata_add: + display_implemented: "true" + progress_score: "n+1" + next_section_and_step: "drop_piece:explain_drop" + correct: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + metadata_add: + display_implemented: "true" + progress_score: "n+1" + next_section_and_step: "drop_piece:explain_drop" + partial: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + next_section_and_step: "display_board:implement_display" + needs_help: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + next_section_and_step: "display_board:implement_display" + set_language: + content_blocks: + - "Language updated!" + metadata_add: + programming_language: "the-users-response" + counts_as_attempt: false + next_section_and_step: "display_board:implement_display" + + - section_id: "drop_piece" + title: "Step 3: Dropping a Piece" + steps: + - step_id: "explain_drop" + title: "Understanding Gravity" + content_blocks: + - "# 🪂 Step 3: Dropping a Piece (Gravity!)" + - "" + - "Now for the fun part: actually playing the game!" + - "" + - "**The Physics:** When you drop a piece in a column, it falls to the lowest empty space in that column." + - "" + - "**Algorithm Challenge:**" + - "1. Given a column number (0-6)" + - "2. Start from the BOTTOM row (row 5)" + - "3. Move UP until you find an empty space" + - "4. Place the piece there" + - "" + - "**Think about it:** If column 3 has pieces in rows 5, 4, and 3 (bottom three rows), the next piece drops into row 2." + - "" + - "**Tip:** You can iterate from the bottom up, or from top down and find the first empty, then check the one below is occupied." + + - step_id: "implement_drop" + title: "Write Drop Function" + question: "Write a function drop_piece(board, column, player) that drops a player's piece (e.g., 'X' or 'O') into the specified column. It should find the lowest empty row in that column and place the piece there. Return True if successful, False if the column is full." + tokens_for_ai: | + Get the programming language from metadata.programming_language. + + The student should implement the drop logic with gravity. + + Categorize as 'excellent' if they: + - Iterate through rows correctly (bottom-up or top-down) + - Find the lowest empty space + - Place the piece + - Return True/False or similar success indicator + - Handle full column edge case + + Categorize as 'correct' if they: + - Core gravity logic works + - Minor issues with iteration direction + - Concept is clearly understood + + Categorize as 'wrong_direction' if they: + - Place pieces at the top instead of letting them fall + - But understand they need to find an empty space + + Categorize as 'needs_guidance' if they're struggling with the algorithm. + + Categorize as 'set_language' for language changes. + feedback_tokens_for_ai: | + Provide feedback in metadata.programming_language. + + If excellent/correct: + - Celebrate: "Perfect! Gravity works! 🌍" + - Explain how this function will be called each turn + - Mention: "This is the core game mechanic working!" + - Suggest they could add error checking (invalid column numbers) + + If wrong_direction: + - Point out pieces should FALL to the bottom + - Suggest: "Start checking from row 5 (bottom) and move up" + - Or: "Check from row 0 (top) down, but place in the LAST empty row" + + If needs_guidance: + - Walk through an example: "Column 2 is empty. Where does the first piece go? Row 5 (bottom)." + - "Second piece? Row 4. Third piece? Row 3." + - Give pseudocode for the loop structure + buckets: [excellent, correct, wrong_direction, needs_guidance, set_language] + transitions: + excellent: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + metadata_add: + drop_implemented: "true" + progress_score: "n+1" + next_section_and_step: "validate_moves:explain_validation" + correct: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + metadata_add: + drop_implemented: "true" + progress_score: "n+1" + next_section_and_step: "validate_moves:explain_validation" + wrong_direction: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + next_section_and_step: "drop_piece:implement_drop" + needs_guidance: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + next_section_and_step: "drop_piece:implement_drop" + set_language: + content_blocks: + - "Language updated!" + metadata_add: + programming_language: "the-users-response" + counts_as_attempt: false + next_section_and_step: "drop_piece:implement_drop" + + - section_id: "validate_moves" + title: "Step 4: Validating Moves" + steps: + - step_id: "explain_validation" + title: "Input Validation" + content_blocks: + - "# ✅ Step 4: Validating Moves" + - "" + - "Before dropping a piece, we need to check if the move is legal!" + - "" + - "**Invalid Moves:**" + - "1. Column number is out of range (< 0 or > 6)" + - "2. Column is already full (all 6 rows occupied)" + - "" + - "**Why This Matters:** Without validation, your game will crash or behave unexpectedly when players make mistakes." + - "" + - "**Good User Experience:** Tell players WHY their move was invalid and let them try again." + + - step_id: "implement_validation" + title: "Write Validation Function" + question: "Write a function is_valid_move(board, column) that returns True if the move is valid (column is in range 0-6 and not full), False otherwise. Bonus: Write a function get_player_move() that keeps asking until the player enters a valid column." + tokens_for_ai: | + Get the programming language from metadata.programming_language. + + Categorize as 'excellent' if they: + - Check column range (0-6) + - Check if column has any empty space + - Return boolean correctly + - Bonus: Implement get_player_move with retry loop + + Categorize as 'correct' if they: + - Have validation logic for both conditions + - Function structure is correct + - Minor syntax issues okay + + Categorize as 'partial' if they: + - Only check one condition (range OR fullness) + - Concept understood but incomplete + + Categorize as 'needs_help' if struggling with the logic. + + Categorize as 'set_language' for language changes. + feedback_tokens_for_ai: | + Provide feedback in metadata.programming_language. + + If excellent: + - Celebrate: "Excellent validation! Your game is robust! 💪" + - If they did the bonus: "Love the input loop - great UX!" + - Point out how this prevents crashes and improves player experience + + If correct: + - Praise: "Great! Your validation works!" + - If they didn't do the bonus, mention it would be a nice addition + + If partial: + - Identify what they got right + - Explain what's missing (range check or fullness check) + - Encourage them to add the missing piece + + If needs_help: + - Break it down: "Two checks needed:" + - "1. Is 0 <= column <= 6?" + - "2. Is the top row (row 0) of that column empty?" + - Provide pseudocode structure + buckets: [excellent, correct, partial, needs_help, set_language] + transitions: + excellent: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + metadata_add: + validation_implemented: "true" + progress_score: "n+1" + next_section_and_step: "horizontal_win:explain_horizontal" + correct: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + metadata_add: + validation_implemented: "true" + progress_score: "n+1" + next_section_and_step: "horizontal_win:explain_horizontal" + partial: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + next_section_and_step: "validate_moves:implement_validation" + needs_help: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + next_section_and_step: "validate_moves:implement_validation" + set_language: + content_blocks: + - "Language updated!" + metadata_add: + programming_language: "the-users-response" + counts_as_attempt: false + next_section_and_step: "validate_moves:implement_validation" + + - section_id: "horizontal_win" + title: "Step 5: Checking Horizontal Wins" + steps: + - step_id: "explain_horizontal" + title: "Win Detection - Horizontal" + content_blocks: + - "# 🏆 Step 5: Detecting Horizontal Wins" + - "" + - "Now for the game logic - determining when someone wins!" + - "" + - "**Horizontal Win:** 4 identical pieces in a row (same row, consecutive columns)" + - "" + - "**Algorithm Strategy:**" + - "1. For each row (0-5)" + - "2. For each starting column (0-3) - why only 0-3? Because you need 4 consecutive!" + - "3. Check if board[row][col], board[row][col+1], board[row][col+2], board[row][col+3] are all the same player" + - "" + - "**Key Insight:** You only need to check columns 0-3 as starting positions. If you start at column 4, you can't fit 4 pieces!" + + - step_id: "implement_horizontal" + title: "Write Horizontal Check" + question: "Write a function check_horizontal_win(board, player) that returns True if the specified player has 4 in a row horizontally, False otherwise. Iterate through all rows and check consecutive columns." + tokens_for_ai: | + Get the programming language from metadata.programming_language. + + Categorize as 'excellent' if they: + - Iterate rows (0-5) correctly + - Iterate columns (0-3) as starting positions + - Check 4 consecutive positions + - Compare against player symbol + - Return True when found, False at end + + Categorize as 'correct' if they: + - Logic is sound + - Might iterate all columns but still works + - Core concept demonstrated + + Categorize as 'wrong_bounds' if they: + - Iterate columns 0-6 (causing index errors) + - But understand the consecutive checking concept + + Categorize as 'needs_guidance' if struggling with the nested loops or logic. + + Categorize as 'set_language' for language changes. + feedback_tokens_for_ai: | + Provide feedback in metadata.programming_language. + + If excellent: + - Celebrate: "Perfect! Horizontal wins are detected! 🎉" + - Mention: "Your optimization (only checking columns 0-3) is smart!" + - Hint at what's next: "Vertical and diagonal will use similar patterns" + + If correct: + - Praise: "Great logic!" + - If they checked all columns unnecessarily, gently suggest the optimization + - Still move them forward + + If wrong_bounds: + - Point out the index error: "Checking column 6 means accessing [row][6+3] which doesn't exist!" + - Explain: "If you start at column 4, you check positions 4,5,6,7 - but column 7 doesn't exist" + - Suggest: "Only iterate columns 0-3" + + If needs_guidance: + - Walk through a concrete example + - "Row 2, starting at column 1: check [2][1], [2][2], [2][3], [2][4]" + - Provide pseudocode structure + buckets: [excellent, correct, wrong_bounds, needs_guidance, set_language] + transitions: + excellent: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + metadata_add: + horizontal_implemented: "true" + progress_score: "n+1" + next_section_and_step: "vertical_win:explain_vertical" + correct: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + metadata_add: + horizontal_implemented: "true" + progress_score: "n+1" + next_section_and_step: "vertical_win:explain_vertical" + wrong_bounds: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + next_section_and_step: "horizontal_win:implement_horizontal" + needs_guidance: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + next_section_and_step: "horizontal_win:implement_horizontal" + set_language: + content_blocks: + - "Language updated!" + metadata_add: + programming_language: "the-users-response" + counts_as_attempt: false + next_section_and_step: "horizontal_win:implement_horizontal" + + - section_id: "vertical_win" + title: "Step 6: Checking Vertical Wins" + steps: + - step_id: "explain_vertical" + title: "Win Detection - Vertical" + content_blocks: + - "# 📏 Step 6: Detecting Vertical Wins" + - "" + - "Similar to horizontal, but now we're checking columns instead of rows!" + - "" + - "**Vertical Win:** 4 identical pieces stacked vertically (same column, consecutive rows)" + - "" + - "**Algorithm Strategy:**" + - "1. For each column (0-6)" + - "2. For each starting row (0-2) - why only 0-2? Same reason as before!" + - "3. Check if board[row][col], board[row+1][col], board[row+2][col], board[row+3][col] are all the same player" + - "" + - "**Pattern Recognition:** Notice how this mirrors the horizontal check, just with rows and columns swapped?" + + - step_id: "implement_vertical" + title: "Write Vertical Check" + question: "Write a function check_vertical_win(board, player) that returns True if the specified player has 4 in a row vertically. Use the same logic as horizontal, but swap rows and columns." + tokens_for_ai: | + Get the programming language from metadata.programming_language. + + Categorize as 'excellent' if they: + - Iterate columns (0-6) correctly + - Iterate rows (0-2) as starting positions + - Check 4 consecutive rows in same column + - Compare against player symbol + - Return boolean correctly + + Categorize as 'correct' if they: + - Logic works + - Might iterate all rows but function still works + - Understand the pattern + + Categorize as 'wrong_bounds' if they: + - Iterate rows 0-5 (causing index errors on row+3) + - But the checking logic is right + + Categorize as 'needs_guidance' if struggling. + + Categorize as 'set_language' for language changes. + feedback_tokens_for_ai: | + Provide feedback in metadata.programming_language. + + If excellent: + - Celebrate: "Vertical wins detected! 📏 You're seeing the patterns!" + - Mention: "Notice how similar this is to horizontal? Same algorithm, different direction!" + - Build anticipation: "Diagonal is the trickiest one next!" + + If correct: + - Praise: "Great work!" + - If they checked all rows, gently suggest the optimization + - Acknowledge they're building momentum + + If wrong_bounds: + - Explain the index issue with row+3 exceeding bounds + - Suggest: "Only start from rows 0-2" + + If needs_guidance: + - Remind them of horizontal logic + - "It's the same pattern, just checking board[row+i][col] instead of board[row][col+i]" + - Provide structure + buckets: [excellent, correct, wrong_bounds, needs_guidance, set_language] + transitions: + excellent: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + metadata_add: + vertical_implemented: "true" + progress_score: "n+1" + next_section_and_step: "diagonal_win:explain_diagonal" + correct: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + metadata_add: + vertical_implemented: "true" + progress_score: "n+1" + next_section_and_step: "diagonal_win:explain_diagonal" + wrong_bounds: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + next_section_and_step: "vertical_win:implement_vertical" + needs_guidance: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + next_section_and_step: "vertical_win:implement_vertical" + set_language: + content_blocks: + - "Language updated!" + metadata_add: + programming_language: "the-users-response" + counts_as_attempt: false + next_section_and_step: "vertical_win:implement_vertical" + + - section_id: "diagonal_win" + title: "Step 7: Checking Diagonal Wins" + steps: + - step_id: "explain_diagonal" + title: "Win Detection - Diagonals" + content_blocks: + - "# ↗️ Step 7: Detecting Diagonal Wins (The Tricky One!)" + - "" + - "Diagonals are the most challenging because there are TWO directions to check!" + - "" + - "**Two Types of Diagonals:**" + - "1. **Down-Right (↘️):** row increases, column increases (row+1, col+1)" + - "2. **Up-Right (↗️):** row decreases, column increases (row-1, col+1)" + - "" + - "**Down-Right Diagonal:**" + - "- Starting row range: 0-2 (need room to go down 3 rows)" + - "- Starting column range: 0-3 (need room to go right 3 columns)" + - "- Check: [row][col], [row+1][col+1], [row+2][col+2], [row+3][col+3]" + - "" + - "**Up-Right Diagonal:**" + - "- Starting row range: 3-5 (need room to go up 3 rows)" + - "- Starting column range: 0-3 (need room to go right 3 columns)" + - "- Check: [row][col], [row-1][col+1], [row-2][col+2], [row-3][col+3]" + + - step_id: "implement_diagonal" + title: "Write Diagonal Check" + question: "Write a function check_diagonal_win(board, player) that returns True if the player has 4 in a row diagonally (either direction). You need to check both down-right (↘️) and up-right (↗️) diagonals." + tokens_for_ai: | + Get the programming language from metadata.programming_language. + + This is the hardest check! Be generous with partial credit. + + Categorize as 'excellent' if they: + - Check BOTH diagonal directions + - Correct row/column bounds for each direction + - Proper indexing (row±i, col+i) + - Return True when found + + Categorize as 'correct' if they: + - Have both directions + - Logic is mostly right + - Minor boundary or indexing issues but concept clear + + Categorize as 'one_direction' if they: + - Only implement one diagonal direction + - But that direction is implemented correctly + + Categorize as 'needs_guidance' if they're struggling with the concept. + + Categorize as 'set_language' for language changes. + feedback_tokens_for_ai: | + Provide feedback in metadata.programming_language. + + If excellent: + - Celebrate enthusiastically: "🎉 You conquered diagonals! This is the hardest part!" + - Praise: "Both directions working correctly - impressive!" + - Mention: "Win detection is now COMPLETE! Your game knows when someone wins!" + + If correct: + - Praise: "Great work on the tricky diagonal logic!" + - If minor issues, point them out gently + - Still acknowledge this is hard and they did well + + If one_direction: + - Praise what they did: "Excellent work on [direction] diagonals!" + - Explain: "Connect Four needs both directions: ↘️ and ↗️" + - Guide them on the second direction's bounds and indexing + + If needs_guidance: + - Break down one diagonal type completely + - "Down-right example: start at [0][0], check [0][0], [1][1], [2][2], [3][3]" + - "Start at [1][2], check [1][2], [2][3], [3][4], [4][5]" + - Provide pseudocode structure + buckets: [excellent, correct, one_direction, needs_guidance, set_language] + transitions: + excellent: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + metadata_add: + diagonal_implemented: "true" + progress_score: "n+1" + next_section_and_step: "game_loop:explain_loop" + correct: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + metadata_add: + diagonal_implemented: "true" + progress_score: "n+1" + next_section_and_step: "game_loop:explain_loop" + one_direction: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + next_section_and_step: "diagonal_win:implement_diagonal" + needs_guidance: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + next_section_and_step: "diagonal_win:implement_diagonal" + set_language: + content_blocks: + - "Language updated!" + metadata_add: + programming_language: "the-users-response" + counts_as_attempt: false + next_section_and_step: "diagonal_win:implement_diagonal" + + - section_id: "game_loop" + title: "Step 8: Building the Game Loop" + steps: + - step_id: "explain_loop" + title: "Putting It All Together" + content_blocks: + - "# 🔄 Step 8: The Game Loop" + - "" + - "You have ALL the pieces! Now let's assemble them into a playable game." + - "" + - "**Game Loop Structure:**" + - "1. Initialize the board" + - "2. Set current player (start with Player 1)" + - "3. **Loop until game ends:**" + - " - Display the board" + - " - Get current player's move (with validation)" + - " - Drop the piece" + - " - Check if current player won (all 3 directions)" + - " - Check if board is full (tie)" + - " - Switch to other player" + - "4. Display final board and announce winner" + - "" + - "**Key Concepts:**" + - "- **Game state:** The board changes each turn" + - "- **Turn alternation:** Switch between players" + - "- **Exit condition:** Win or tie breaks the loop" + + - step_id: "implement_loop" + title: "Write Game Loop" + question: "Write the main game loop that brings everything together. Initialize the board, alternate between two players, validate moves, drop pieces, check for wins, and announce the winner. You can write this as a play_game() function or as main program logic." + tokens_for_ai: | + Get the programming language from metadata.programming_language. + + They're writing the FULL game now! Be encouraging. + + Categorize as 'excellent' if they: + - Initialize board + - Have a game loop (while/for loop until game ends) + - Alternate between players + - Call display, input, validation, drop, and win check functions + - Handle both win and tie conditions + - Announce results + + Categorize as 'correct' if they: + - Have the main structure + - Loop with turn alternation + - Call their functions appropriately + - Minor logic issues okay if concept is clear + + Categorize as 'partial' if they: + - Have some of the structure + - Missing key parts (like win checking or player switching) + - On the right track but incomplete + + Categorize as 'needs_guidance' if they're struggling to put it together. + + Categorize as 'set_language' for language changes. + feedback_tokens_for_ai: | + Provide feedback in metadata.programming_language. + + If excellent: + - CELEBRATE BIG: "🎉🎮 YOU DID IT! You built a complete Connect Four game!" + - List what they've accomplished: + * Board representation with 2D arrays + * Display with nested loops + * Gravity simulation for dropping pieces + * Input validation + * Win detection in 3 directions + * Full game loop with turn management + - Suggest enhancements: AI opponent, GUI, undo moves, score tracking + - Congratulate them on completing a non-trivial project! + + If correct: + - Celebrate: "Your game works! Excellent job! 🎉" + - Point out any minor improvements + - Still emphasize they built something real and playable + + If partial: + - Praise what's working + - Identify what's missing + - Guide them: "You have X and Y working. Now add Z to complete the loop." + - Encourage: "You're so close!" + + If needs_guidance: + - Break down the loop structure + - "Think of it as: setup -> loop (input, validate, drop, check, switch) -> end" + - Provide high-level pseudocode + - Encourage them to try integrating one piece at a time + buckets: [excellent, correct, partial, needs_guidance, set_language] + transitions: + excellent: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + metadata_add: + game_complete: "true" + progress_score: "n+1" + next_section_and_step: "conclusion:reflection" + correct: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + metadata_add: + game_complete: "true" + progress_score: "n+1" + next_section_and_step: "conclusion:reflection" + partial: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + next_section_and_step: "game_loop:implement_loop" + needs_guidance: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + next_section_and_step: "game_loop:implement_loop" + set_language: + content_blocks: + - "Language updated!" + metadata_add: + programming_language: "the-users-response" + counts_as_attempt: false + next_section_and_step: "game_loop:implement_loop" + + - section_id: "conclusion" + title: "Conclusion & Reflection" + steps: + - step_id: "reflection" + title: "What You've Learned" + question: "Reflect on what you learned. What was the most challenging part? What concepts (2D arrays, loops, algorithms, etc.) do you feel more confident about now? What would you add to your game next?" + tokens_for_ai: | + This is a reflection question. Accept any thoughtful response. + + Categorize as 'thoughtful' if they: + - Reflect on specific challenges (likely diagonals!) + - Mention concepts they learned + - Show understanding of what they built + - Maybe mention enhancements + + Categorize as 'brief' if they: + - Give a short but genuine response + - Show they completed the project + + Categorize as 'off_topic' if they: + - Don't engage with the reflection + - Are completely off-topic + + Categorize as 'set_language' for language changes (though activity is ending). + feedback_tokens_for_ai: | + Provide encouraging, celebratory feedback. + + For thoughtful responses: + - Acknowledge their specific insights + - Validate that diagonals ARE the hardest part + - Encourage them to implement their enhancement ideas + - Mention how these concepts (2D arrays, nested loops, algorithms) apply to many other programs + - Celebrate their achievement of building a complete game from scratch + + For brief responses: + - Thank them for their time + - Celebrate their completion + - Encourage them to keep coding + + For off_topic: + - Gently redirect to the question + - Ask them to reflect on the experience + buckets: [thoughtful, brief, off_topic, set_language] + transitions: + thoughtful: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + metadata_add: + activity_completed: "true" + next_section_and_step: "conclusion:goodbye" + brief: + ai_feedback: + tokens_for_ai: "See feedback_tokens_for_ai above" + metadata_add: + activity_completed: "true" + next_section_and_step: "conclusion:goodbye" + off_topic: + content_blocks: + - "Let's take a moment to reflect on what you learned building Connect Four." + next_section_and_step: "conclusion:reflection" + set_language: + content_blocks: + - "Language updated! Though we're at the end of the activity." + metadata_add: + programming_language: "the-users-response" + counts_as_attempt: false + next_section_and_step: "conclusion:reflection" + + - step_id: "goodbye" + title: "Congratulations!" + content_blocks: + - "# 🎉 Congratulations! You Built Connect Four! 🎮" + - "" + - "You've successfully created a fully functional Connect Four game from scratch!" + - "" + - "**What You Accomplished:**" + - "✅ Mastered 2D arrays and nested data structures" + - "✅ Implemented game physics (gravity!)" + - "✅ Wrote input validation" + - "✅ Designed win-detection algorithms in 3 directions" + - "✅ Built a complete game loop with state management" + - "✅ Created something you can actually play!" + - "" + - "**Next Steps:**" + - "- Add an AI opponent (minimax algorithm?)" + - "- Create a graphical interface (GUI)" + - "- Add animations for falling pieces" + - "- Implement undo/redo" + - "- Add different board sizes" + - "" + - "Keep building! Every complex program is just these same concepts combined in creative ways. 🚀" + - "" + - "Happy coding!"