All skills
jamesrochabrun avatar

/math-teacher

@98139d5

Interactive math teacher that instantly generates playful, gamified learning experiences. Creates visual playgrounds, interactive artifacts, and engaging games for kids and adults to learn math concepts from basic arithmetic to advanced calculus.

Use this Skill: https://skilld.dev/gh/jamesrochabrun/skills/math-teacher

This session only. Nothing lands on disk.

referencesalgebra.md

≈3k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Algebra Reference

Algebraic concepts and interactive visualizations for middle school to high school.

Variables & Expressions

Visual Variables

// Mystery box representation
function drawVariable(name, value, canvas) {
  const ctx = canvas.getContext('2d');

  // Draw box
  ctx.fillStyle = '#667eea';
  ctx.fillRect(50, 50, 100, 100);
  ctx.strokeStyle = '#333';
  ctx.lineWidth = 3;
  ctx.strokeRect(50, 50, 100, 100);

  // Variable name
  ctx.fillStyle = 'white';
  ctx.font = 'bold 40px Arial';
  ctx.textAlign = 'center';
  ctx.fillText(name, 100, 110);

  // Value (revealed)
  if (value !== undefined) {
    ctx.fillStyle = '#FFD700';
    ctx.font = 'bold 30px Arial';
    ctx.fillText(`= ${value}`, 100, 170);
  } else {
    ctx.fillStyle = '#FFF';
    ctx.font = '20px Arial';
    ctx.fillText('?', 100, 170);
  }
}

Expression Evaluator

function evaluateExpression(expr, variables) {
  // Replace variables with values
  let result = expr;
  for (const [name, value] of Object.entries(variables)) {
    result = result.replace(new RegExp(name, 'g'), value);
  }

  try {
    return {
      expression: expr,
      substituted: result,
      result: eval(result),
      steps: showSteps(expr, variables)
    };
  } catch (e) {
    return { error: 'Invalid expression' };
  }
}

function showSteps(expr, variables) {
  const steps = [];
  steps.push(`Original: ${expr}`);

  let current = expr;
  for (const [name, value] of Object.entries(variables)) {
    current = current.replace(new RegExp(name, 'g'), value);
    steps.push(`Substitute ${name} = ${value}: ${current}`);
  }

  steps.push(`Evaluate: ${eval(current)}`);
  return steps;
}

Linear Equations

Equation Solver

// Solve ax + b = c for x
function solveLinear(a, b, c) {
  const x = (c - b) / a;

  return {
    equation: `${a}x + ${b} = ${c}`,
    steps: [
      `${a}x + ${b} = ${c}`,
      `${a}x = ${c - b}`,
      `x = ${(c - b)}/${a}`,
      `x = ${x}`
    ],
    solution: x,
    verification: `${a}(${x}) + ${b} = ${a * x + b} ✓`
  };
}

Balance Scale Visualization

function drawBalanceScale(left, right, canvas) {
  const ctx = canvas.getContext('2d');
  const centerX = canvas.width / 2;
  const centerY = canvas.height / 2;

  // Calculate balance
  const diff = left - right;
  const angle = Math.atan(diff / 10);

  // Draw fulcrum
  ctx.fillStyle = '#333';
  ctx.beginPath();
  ctx.moveTo(centerX - 20, centerY + 50);
  ctx.lineTo(centerX, centerY);
  ctx.lineTo(centerX + 20, centerY + 50);
  ctx.closePath();
  ctx.fill();

  // Draw beam
  ctx.save();
  ctx.translate(centerX, centerY);
  ctx.rotate(angle);

  ctx.fillStyle = '#8B4513';
  ctx.fillRect(-150, -10, 300, 20);

  // Left side
  ctx.fillStyle = '#667eea';
  ctx.fillRect(-140, -60, 80, 80);
  ctx.fillStyle = 'white';
  ctx.font = 'bold 24px Arial';
  ctx.textAlign = 'center';
  ctx.fillText(left, -100, -10);

  // Right side
  ctx.fillStyle = '#FF6347';
  ctx.fillRect(60, -60, 80, 80);
  ctx.fillStyle = 'white';
  ctx.fillText(right, 100, -10);

  ctx.restore();

  // Status
  ctx.fillStyle = '#333';
  ctx.font = '20px Arial';
  ctx.textAlign = 'center';
  const status = Math.abs(diff) < 0.1 ? '⚖️ Balanced!' :
                 diff > 0 ? '⬅️ Left heavier' : '➡️ Right heavier';
  ctx.fillText(status, centerX, centerY + 100);
}

Quadratic Equations

Quadratic Formula

function solveQuadratic(a, b, c) {
  const discriminant = b * b - 4 * a * c;

  const result = {
    equation: `${a}x² + ${b}x + ${c} = 0`,
    discriminant: discriminant,
    a, b, c
  };

  if (discriminant > 0) {
    const x1 = (-b + Math.sqrt(discriminant)) / (2 * a);
    const x2 = (-b - Math.sqrt(discriminant)) / (2 * a);
    result.solutions = [x1, x2];
    result.type = 'Two real solutions';
    result.message = '🎉 Two x-intercepts!';
  } else if (discriminant === 0) {
    const x = -b / (2 * a);
    result.solutions = [x];
    result.type = 'One real solution';
    result.message = '🎯 One x-intercept (vertex on x-axis)!';
  } else {
    const realPart = -b / (2 * a);
    const imagPart = Math.sqrt(-discriminant) / (2 * a);
    result.solutions = [
      `${realPart} + ${imagPart}i`,
      `${realPart} - ${imagPart}i`
    ];
    result.type = 'Two complex solutions';
    result.message = '👻 No x-intercepts (complex numbers)!';
  }

  return result;
}

Parabola Grapher

function drawParabola(a, b, c, canvas) {
  const ctx = canvas.getContext('2d');
  const width = canvas.width;
  const height = canvas.height;

  // Clear canvas
  ctx.clearRect(0, 0, width, height);

  // Draw axes
  drawAxes(ctx, width, height);

  // Calculate vertex
  const vertexX = -b / (2 * a);
  const vertexY = a * vertexX * vertexX + b * vertexX + c;

  // Draw parabola
  ctx.beginPath();
  ctx.strokeStyle = '#667eea';
  ctx.lineWidth = 3;

  for (let x = -10; x <= 10; x += 0.1) {
    const y = a * x * x + b * x + c;
    const px = (x + 10) * (width / 20);
    const py = height - ((y + 10) * (height / 20));

    if (x === -10) ctx.moveTo(px, py);
    else ctx.lineTo(px, py);
  }
  ctx.stroke();

  // Mark vertex
  const vx = (vertexX + 10) * (width / 20);
  const vy = height - ((vertexY + 10) * (height / 20));

  ctx.fillStyle = '#FF6347';
  ctx.beginPath();
  ctx.arc(vx, vy, 8, 0, Math.PI * 2);
  ctx.fill();

  // Vertex label
  ctx.fillStyle = '#333';
  ctx.font = '14px Arial';
  ctx.fillText(`Vertex: (${vertexX.toFixed(2)}, ${vertexY.toFixed(2)})`,
               vx + 10, vy - 10);

  // Draw axis of symmetry
  ctx.strokeStyle = '#FFD700';
  ctx.setLineDash([5, 5]);
  ctx.beginPath();
  ctx.moveTo(vx, 0);
  ctx.lineTo(vx, height);
  ctx.stroke();
  ctx.setLineDash([]);

  return { vertexX, vertexY };
}

function drawAxes(ctx, width, height) {
  ctx.strokeStyle = '#CCC';
  ctx.lineWidth = 1;

  // X-axis
  ctx.beginPath();
  ctx.moveTo(0, height / 2);
  ctx.lineTo(width, height / 2);
  ctx.stroke();

  // Y-axis
  ctx.beginPath();
  ctx.moveTo(width / 2, 0);
  ctx.lineTo(width / 2, height);
  ctx.stroke();

  // Grid
  ctx.strokeStyle = '#F0F0F0';
  for (let i = 0; i < width; i += width / 20) {
    ctx.beginPath();
    ctx.moveTo(i, 0);
    ctx.lineTo(i, height);
    ctx.stroke();
  }
  for (let i = 0; i < height; i += height / 20) {
    ctx.beginPath();
    ctx.moveTo(0, i);
    ctx.lineTo(width, i);
    ctx.stroke();
  }
}

Functions

Function Visualizer

const commonFunctions = {
  linear: (x, m, b) => m * x + b,
  quadratic: (x, a, b, c) => a * x * x + b * x + c,
  cubic: (x, a) => a * x * x * x,
  exponential: (x, a) => Math.pow(a, x),
  logarithmic: (x, a) => Math.log(x) / Math.log(a),
  sine: (x, a) => a * Math.sin(x),
  cosine: (x, a) => a * Math.cos(x),
  absolute: (x) => Math.abs(x),
  squareRoot: (x) => Math.sqrt(x)
};

function plotFunction(fn, xMin, xMax, canvas) {
  const ctx = canvas.getContext('2d');
  const width = canvas.width;
  const height = canvas.height;

  drawAxes(ctx, width, height);

  ctx.beginPath();
  ctx.strokeStyle = '#667eea';
  ctx.lineWidth = 3;

  const step = (xMax - xMin) / width;
  for (let x = xMin; x <= xMax; x += step) {
    try {
      const y = fn(x);
      if (!isNaN(y) && isFinite(y)) {
        const px = ((x - xMin) / (xMax - xMin)) * width;
        const py = height - ((y - (-10)) / 20) * height;

        if (x === xMin) ctx.moveTo(px, py);
        else ctx.lineTo(px, py);
      }
    } catch (e) {
      // Skip invalid points
    }
  }
  ctx.stroke();
}

Domain & Range Finder

function analyzeFunctionDomainRange(type, params) {
  const analysis = {
    type: type,
    params: params
  };

  switch(type) {
    case 'linear':
      analysis.domain = '(-∞, ∞)';
      analysis.range = '(-∞, ∞)';
      break;
    case 'quadratic':
      const a = params.a;
      const vertex = -params.b / (2 * a);
      const vertexY = a * vertex * vertex + params.b * vertex + params.c;
      analysis.domain = '(-∞, ∞)';
      analysis.range = a > 0 ? `[${vertexY.toFixed(2)}, ∞)` :
                                `(-∞, ${vertexY.toFixed(2)}]`;
      analysis.vertex = { x: vertex, y: vertexY };
      break;
    case 'squareRoot':
      analysis.domain = '[0, ∞)';
      analysis.range = '[0, ∞)';
      break;
    case 'logarithmic':
      analysis.domain = '(0, ∞)';
      analysis.range = '(-∞, ∞)';
      break;
  }

  return analysis;
}

Systems of Equations

Graphical Solution

function solveSystemGraphically(eq1, eq2, canvas) {
  // eq1 and eq2 are linear equations in form {m: slope, b: intercept}

  const ctx = canvas.getContext('2d');
  const width = canvas.width;
  const height = canvas.height;

  drawAxes(ctx, width, height);

  // Plot first equation
  ctx.strokeStyle = '#667eea';
  ctx.lineWidth = 3;
  ctx.beginPath();
  for (let x = -10; x <= 10; x += 0.1) {
    const y = eq1.m * x + eq1.b;
    const px = (x + 10) * (width / 20);
    const py = height - ((y + 10) * (height / 20));
    if (x === -10) ctx.moveTo(px, py);
    else ctx.lineTo(px, py);
  }
  ctx.stroke();

  // Plot second equation
  ctx.strokeStyle = '#FF6347';
  ctx.beginPath();
  for (let x = -10; x <= 10; x += 0.1) {
    const y = eq2.m * x + eq2.b;
    const px = (x + 10) * (width / 20);
    const py = height - ((y + 10) * (height / 20));
    if (x === -10) ctx.moveTo(px, py);
    else ctx.lineTo(px, py);
  }
  ctx.stroke();

  // Find intersection
  // eq1.m * x + eq1.b = eq2.m * x + eq2.b
  // (eq1.m - eq2.m) * x = eq2.b - eq1.b
  const x = (eq2.b - eq1.b) / (eq1.m - eq2.m);
  const y = eq1.m * x + eq1.b;

  // Mark intersection
  const px = (x + 10) * (width / 20);
  const py = height - ((y + 10) * (height / 20));

  ctx.fillStyle = '#FFD700';
  ctx.beginPath();
  ctx.arc(px, py, 10, 0, Math.PI * 2);
  ctx.fill();

  ctx.fillStyle = '#333';
  ctx.font = 'bold 16px Arial';
  ctx.fillText(`(${x.toFixed(2)}, ${y.toFixed(2)})`, px + 15, py - 15);

  return { x, y };
}

Polynomials

Polynomial Evaluator

function evaluatePolynomial(coefficients, x) {
  // coefficients = [a0, a1, a2, ...] for a0 + a1*x + a2*x^2 + ...
  let result = 0;
  let term = 1;

  const terms = [];
  for (let i = 0; i < coefficients.length; i++) {
    const value = coefficients[i] * term;
    result += value;
    terms.push({
      coefficient: coefficients[i],
      power: i,
      value: value,
      display: i === 0 ? `${coefficients[i]}` :
               i === 1 ? `${coefficients[i]}x` :
               `${coefficients[i]}x^${i}`
    });
    term *= x;
  }

  return {
    x: x,
    result: result,
    terms: terms,
    polynomial: formatPolynomial(coefficients)
  };
}

function formatPolynomial(coefficients) {
  return coefficients.map((c, i) => {
    if (c === 0) return '';
    if (i === 0) return `${c}`;
    if (i === 1) return `${c}x`;
    return `${c}x^${i}`;
  }).filter(t => t).join(' + ');
}

Interactive Elements

Slider for Coefficients

function createCoefficientSliders(equation) {
  const sliders = {};
  const params = ['a', 'b', 'c'];

  params.forEach(param => {
    const slider = document.createElement('input');
    slider.type = 'range';
    slider.min = -10;
    slider.max = 10;
    slider.step = 0.1;
    slider.value = equation[param] || 0;

    slider.addEventListener('input', () => {
      equation[param] = parseFloat(slider.value);
      updateGraph();
      updateEquationDisplay();
    });

    sliders[param] = slider;
  });

  return sliders;
}

Summary

Algebra patterns provide:

  • Visual equation solving with balance scales
  • Interactive function graphing
  • Step-by-step solutions
  • Real-time parameter manipulation
  • Geometric representations of algebraic concepts

These tools make abstract algebra concrete and interactive!

Source: SKILL.md on GitHub

3 warnings16d5 checks · Risk MEDIUM
  • Gen Agent Trust Hub16d

    The math-teacher skill provides a platform for generating interactive educational tools but exhibits several security risks, most notably the inclusion of templates that use the unsafe `eval()` function. Additionally, it exposes local system paths and utilizes scripts that bridge the agent's environment to the host operating system, creating potential vectors for code execution and data exposure.

  • Socket16d

    1 alert: gptSecurity

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer7mo

    7/7 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 98139d5. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Dormantupdated 11 months ago

README badge

README badge for jamesrochabrun/skills/math-teacher