> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hopx.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Interactive Programming Tutorials

> Build Codecademy-style interactive learning with step-by-step code execution, progress tracking, hint systems, and solution validation

Build an interactive programming tutorial platform where students learn by writing and executing code step-by-step. This cookbook demonstrates how to create a Codecademy-style learning experience using HopX.

## Overview

Interactive programming tutorials guide students through learning by executing code at each step. The system validates solutions, provides hints, tracks progress, and ensures students understand concepts before moving forward.

## Prerequisites

* HopX API key ([Get one here](https://console.hopx.dev/api-keys))
* Python 3.8+ or Node.js 16+
* Understanding of educational content structure
* Basic knowledge of progress tracking

## Architecture

```
┌──────────────┐
│   Student    │ Submits code
└──────┬───────┘
       │
       ▼
┌─────────────────┐
│  Tutorial       │ Validate, provide hints
│   Engine        │
└──────┬──────────┘
       │
       ▼
┌─────────────────┐
│  HopX Sandbox   │ Execute & validate
└─────────────────┘
```

## Implementation

### Step 1: Tutorial Step Execution

Execute and validate tutorial steps:

<CodeGroup>
  ```python Python theme={null}
  from hopx_ai import Sandbox
  import os
  from typing import Dict, List, Any

  class TutorialStep:
      def __init__(self, step_id: str, instructions: str, solution: str, hints: List[str]):
          self.step_id = step_id
          self.instructions = instructions
          self.solution = solution
          self.hints = hints

  class InteractiveTutorial:
      def __init__(self, api_key: str):
          self.api_key = api_key
          self.sandbox = None
          self.current_step = 0
          self.steps = []
      
      def initialize(self):
          """Initialize tutorial session"""
          self.sandbox = Sandbox.create(
              template="code-interpreter",
              api_key=self.api_key,
              timeout_seconds=3600
          )
      
      def add_step(self, step: TutorialStep):
          """Add tutorial step"""
          self.steps.append(step)
      
      def validate_step(self, step_index: int, student_code: str) -> Dict[str, Any]:
          """Validate student code for a step"""
          step = self.steps[step_index]
          
          # Execute student code
          result = self.sandbox.run_code(student_code, timeout=10)
          
          # Check if solution matches
          solution_result = self.sandbox.run_code(step.solution, timeout=10)
          
          # Compare outputs
          student_output = result.stdout.strip() if result.success else ""
          solution_output = solution_result.stdout.strip() if solution_result.success else ""
          
          passed = student_output == solution_output and result.success
          
          return {
              "passed": passed,
              "student_output": student_output,
              "expected_output": solution_output,
              "hint": step.hints[0] if not passed and step.hints else None,
              "success": result.success
          }
      
      def get_next_hint(self, step_index: int, hint_index: int) -> str:
          """Get hint for current step"""
          step = self.steps[step_index]
          if hint_index < len(step.hints):
              return step.hints[hint_index]
          return "No more hints available"
      
      def cleanup(self):
          """Clean up tutorial session"""
          if self.sandbox:
              self.sandbox.kill()
              self.sandbox = None

  # Usage
  tutorial = InteractiveTutorial(api_key=os.getenv("HOPX_API_KEY"))
  tutorial.initialize()

  # Add steps
  tutorial.add_step(TutorialStep(
      step_id="step_1",
      instructions="Print 'Hello, World!'",
      solution="print('Hello, World!')",
      hints=["Use the print() function", "Remember to use quotes around the text"]
  ))

  # Validate student code
  result = tutorial.validate_step(0, "print('Hello, World!')")
  print(f"Passed: {result['passed']}")

  tutorial.cleanup()
  ```

  ```javascript JavaScript theme={null}
  import { Sandbox } from '@hopx-ai/sdk';

  class TutorialStep {
      constructor(stepId, instructions, solution, hints) {
          this.stepId = stepId;
          this.instructions = instructions;
          this.solution = solution;
          this.hints = hints;
      }
  }

  class InteractiveTutorial {
      constructor(apiKey) {
          this.apiKey = apiKey;
          this.sandbox = null;
          this.currentStep = 0;
          this.steps = [];
      }
      
      async initialize() {
          this.sandbox = await Sandbox.create({
              template: 'code-interpreter',
              apiKey: this.apiKey,
              timeoutSeconds: 3600
          });
      }
      
      addStep(step) {
          this.steps.push(step);
      }
      
      async validateStep(stepIndex, studentCode) {
          const step = this.steps[stepIndex];
          
          // Execute student code
          const result = await this.sandbox.runCode(studentCode, { timeout: 10 });
          
          // Check if solution matches
          const solutionResult = await this.sandbox.runCode(step.solution, { timeout: 10 });
          
          // Compare outputs
          const studentOutput = result.success ? result.stdout.trim() : '';
          const solutionOutput = solutionResult.success ? solutionResult.stdout.trim() : '';
          
          const passed = studentOutput === solutionOutput && result.success;
          
          return {
              passed,
              studentOutput,
              expectedOutput: solutionOutput,
              hint: !passed && step.hints.length > 0 ? step.hints[0] : null,
              success: result.success
          };
      }
      
      getNextHint(stepIndex, hintIndex) {
          const step = this.steps[stepIndex];
          if (hintIndex < step.hints.length) {
              return step.hints[hintIndex];
          }
          return 'No more hints available';
      }
      
      async cleanup() {
          if (this.sandbox) {
              await this.sandbox.kill();
              this.sandbox = null;
          }
      }
  }

  // Usage
  const tutorial = new InteractiveTutorial(process.env.HOPX_API_KEY);
  await tutorial.initialize();

  // Add steps
  tutorial.addStep(new TutorialStep(
      'step_1',
      "Print 'Hello, World!'",
      "print('Hello, World!')",
      ['Use the print() function', 'Remember to use quotes around the text']
  ));

  // Validate student code
  const result = await tutorial.validateStep(0, "print('Hello, World!')");
  console.log(`Passed: ${result.passed}`);

  await tutorial.cleanup();
  ```
</CodeGroup>

### Step 2: Progress Tracking

Track student progress through tutorials:

<CodeGroup>
  ```python Python theme={null}
  class ProgressTracker:
      def __init__(self):
          self.progress = {}
      
      def update_progress(self, student_id: str, step_id: str, passed: bool):
          """Update student progress"""
          if student_id not in self.progress:
              self.progress[student_id] = {
                  "completed_steps": [],
                  "current_step": 0,
                  "total_steps": 0
              }
          
          if passed and step_id not in self.progress[student_id]["completed_steps"]:
              self.progress[student_id]["completed_steps"].append(step_id)
      
      def get_progress(self, student_id: str) -> Dict[str, Any]:
          """Get student progress"""
          if student_id not in self.progress:
              return {
                  "completed_steps": [],
                  "current_step": 0,
                  "completion_percentage": 0
              }
          
          student_progress = self.progress[student_id]
          total = student_progress.get("total_steps", 1)
          completed = len(student_progress["completed_steps"])
          
          return {
              "completed_steps": student_progress["completed_steps"],
              "current_step": student_progress["current_step"],
              "completion_percentage": (completed / total * 100) if total > 0 else 0
          }

  # Usage
  tracker = ProgressTracker()
  tracker.update_progress("student_1", "step_1", True)
  tracker.update_progress("student_1", "step_2", True)

  progress = tracker.get_progress("student_1")
  print(f"Completion: {progress['completion_percentage']:.1f}%")
  ```

  ```javascript JavaScript theme={null}
  class ProgressTracker {
      constructor() {
          this.progress = {};
      }
      
      updateProgress(studentId, stepId, passed) {
          if (!this.progress[studentId]) {
              this.progress[studentId] = {
                  completedSteps: [],
                  currentStep: 0,
                  totalSteps: 0
              };
          }
          
          if (passed && !this.progress[studentId].completedSteps.includes(stepId)) {
              this.progress[studentId].completedSteps.push(stepId);
          }
      }
      
      getProgress(studentId) {
          if (!this.progress[studentId]) {
              return {
                  completedSteps: [],
                  currentStep: 0,
                  completionPercentage: 0
              };
          }
          
          const studentProgress = this.progress[studentId];
          const total = studentProgress.totalSteps || 1;
          const completed = studentProgress.completedSteps.length;
          
          return {
              completedSteps: studentProgress.completedSteps,
              currentStep: studentProgress.currentStep,
              completionPercentage: total > 0 ? (completed / total * 100) : 0
          };
      }
  }

  // Usage
  const tracker = new ProgressTracker();
  tracker.updateProgress('student_1', 'step_1', true);
  tracker.updateProgress('student_1', 'step_2', true);

  const progress = tracker.getProgress('student_1');
  console.log(`Completion: ${progress.completionPercentage.toFixed(1)}%`);
  ```
</CodeGroup>

## Best Practices

1. **Step-by-Step Learning**: Break concepts into small, digestible steps
2. **Immediate Feedback**: Provide instant validation feedback
3. **Progressive Hints**: Offer hints that guide without giving away solutions
4. **Progress Persistence**: Save progress so students can resume

## Related Cookbooks

* [Online Coding Platform](/cookbooks/educational/online-coding-platform) - Full coding platform
* [Coding Interview Platform](/cookbooks/educational/coding-interviews) - Interview preparation

## Next Steps

1. Create tutorial content management system
2. Implement hint system with multiple levels
3. Add progress persistence
4. Create tutorial authoring tools
5. Add analytics and reporting
