feat(lessons): add lessons from client db
This commit is contained in:
768
src/pages/student/lessons/DataRepresentationLesson.tsx
Normal file
768
src/pages/student/lessons/DataRepresentationLesson.tsx
Normal file
@ -0,0 +1,768 @@
|
||||
import React, { useRef, useState, useEffect } from "react";
|
||||
import {
|
||||
ArrowDown,
|
||||
Check,
|
||||
BookOpen,
|
||||
Target,
|
||||
BarChart3,
|
||||
Calculator,
|
||||
Layers,
|
||||
TrendingUp,
|
||||
} from "lucide-react";
|
||||
import FrequencyMeanWidget from "../../../components/lessons/FrequencyMeanWidget";
|
||||
import HistogramBuilderWidget from "../../../components/lessons/HistogramBuilderWidget";
|
||||
import BoxPlotAnatomyWidget from "../../../components/lessons/BoxPlotAnatomyWidget";
|
||||
import BoxPlotComparisonWidget from "../../../components/lessons/BoxPlotComparisonWidget";
|
||||
import DataModifierWidget from "../../../components/lessons/DataModifierWidget";
|
||||
import Quiz from "../../../components/lessons/Quiz";
|
||||
import {
|
||||
DATA_REP_QUIZ_DATA,
|
||||
CENTER_SPREAD_QUIZ_DATA,
|
||||
DISTRIBUTIONS_QUIZ_DATA,
|
||||
} from "../../../utils/constants";
|
||||
import { Frac } from "../../../components/Math";
|
||||
|
||||
interface LessonProps {
|
||||
onFinish?: () => void;
|
||||
}
|
||||
|
||||
const DataRepresentationLesson: React.FC<LessonProps> = ({ onFinish }) => {
|
||||
const [activeSection, setActiveSection] = useState(0);
|
||||
const sectionsRef = useRef<(HTMLElement | null)[]>([]);
|
||||
|
||||
const scrollToSection = (index: number) => {
|
||||
setActiveSection(index);
|
||||
sectionsRef.current[index]?.scrollIntoView({
|
||||
behavior: "smooth",
|
||||
block: "start",
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
const index = sectionsRef.current.indexOf(
|
||||
entry.target as HTMLElement,
|
||||
);
|
||||
if (index !== -1) {
|
||||
setActiveSection(index);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
{ rootMargin: "-20% 0px -60% 0px" },
|
||||
);
|
||||
|
||||
sectionsRef.current.forEach((section) => {
|
||||
if (section) observer.observe(section);
|
||||
});
|
||||
|
||||
return () => observer.disconnect();
|
||||
}, []);
|
||||
|
||||
const SectionMarker = ({
|
||||
index,
|
||||
title,
|
||||
icon: Icon,
|
||||
}: {
|
||||
index: number;
|
||||
title: string;
|
||||
icon: any;
|
||||
}) => {
|
||||
const isActive = activeSection === index;
|
||||
const isPast = activeSection > index;
|
||||
return (
|
||||
<button
|
||||
onClick={() => scrollToSection(index)}
|
||||
className={`flex items-center gap-3 p-3 w-full rounded-lg transition-all ${
|
||||
isActive
|
||||
? "bg-white shadow-md border border-amber-100"
|
||||
: "hover:bg-slate-100"
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
className={`w-8 h-8 rounded-full flex items-center justify-center shrink-0 ${
|
||||
isActive
|
||||
? "bg-amber-600 text-white"
|
||||
: isPast
|
||||
? "bg-amber-400 text-white"
|
||||
: "bg-slate-200 text-slate-500"
|
||||
}`}
|
||||
>
|
||||
{isPast ? (
|
||||
<Check className="w-4 h-4" />
|
||||
) : (
|
||||
<Icon className="w-4 h-4" />
|
||||
)}
|
||||
</div>
|
||||
<div className="text-left">
|
||||
<p
|
||||
className={`text-sm font-bold ${isActive ? "text-amber-900" : "text-slate-600"}`}
|
||||
>
|
||||
{title}
|
||||
</p>
|
||||
</div>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
const allQuizzes = [
|
||||
...DATA_REP_QUIZ_DATA,
|
||||
...CENTER_SPREAD_QUIZ_DATA,
|
||||
...DISTRIBUTIONS_QUIZ_DATA,
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="flex flex-col lg:flex-row min-h-screen">
|
||||
<aside className="w-full lg:w-64 lg:fixed lg:top-20 lg:bottom-0 lg:overflow-y-auto p-4 border-r border-slate-200 bg-slate-50 z-0 hidden lg:block">
|
||||
<nav className="space-y-2">
|
||||
<SectionMarker index={0} title="Frequency & Mean" icon={Calculator} />
|
||||
<SectionMarker index={1} title="Histograms" icon={BarChart3} />
|
||||
<SectionMarker index={2} title="Box Plots" icon={Layers} />
|
||||
<SectionMarker index={3} title="Center & Spread" icon={TrendingUp} />
|
||||
<SectionMarker
|
||||
index={4}
|
||||
title="Effects of Change"
|
||||
icon={Calculator}
|
||||
/>
|
||||
<SectionMarker index={5} title="Comparisons" icon={Target} />
|
||||
<SectionMarker index={6} title="Practice" icon={BookOpen} />
|
||||
</nav>
|
||||
</aside>
|
||||
|
||||
<div className="flex-1 lg:ml-64 p-6 md:p-12 max-w-4xl mx-auto">
|
||||
{/* Section 1: Frequency & Mean */}
|
||||
<section
|
||||
ref={(el) => {
|
||||
sectionsRef.current[0] = el;
|
||||
}}
|
||||
className="min-h-screen flex flex-col justify-center mb-24 pt-20 lg:pt-0"
|
||||
>
|
||||
<h2 className="text-4xl font-extrabold text-slate-900 mb-6">
|
||||
Frequency Tables & Weighted Mean
|
||||
</h2>
|
||||
<div className="prose prose-slate text-lg text-slate-600 mb-8">
|
||||
<p>
|
||||
When calculating the mean from a table, you must use a{" "}
|
||||
<strong>weighted mean</strong>. Simply adding the values in the
|
||||
first column is a common trap! You must multiply each value by its
|
||||
frequency first.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-amber-50 border border-amber-200 rounded-2xl p-6 mb-8">
|
||||
<h3 className="text-lg font-bold text-amber-900 mb-3">
|
||||
The Weighted Mean Formula
|
||||
</h3>
|
||||
<div className="bg-white rounded-xl p-4 text-center mb-4 border border-amber-100">
|
||||
<p className="text-xl font-mono font-bold text-amber-800">
|
||||
Weighted Mean ={" "}
|
||||
<Frac n="Σ(value × frequency)" d="Σ(frequency)" />
|
||||
</p>
|
||||
</div>
|
||||
<p className="text-slate-600 text-base">
|
||||
For each row, multiply the value by its frequency count. Sum all
|
||||
those products, then divide by the total number of data points
|
||||
(the sum of all frequencies).
|
||||
</p>
|
||||
<div className="mt-4 bg-red-50 border border-red-200 rounded-xl p-4">
|
||||
<p className="text-red-800 font-bold text-sm">
|
||||
Common SAT Trap: Do NOT average the values in the first column
|
||||
directly. That ignores how many times each value appears and
|
||||
will almost always give the wrong answer.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<FrequencyMeanWidget />
|
||||
|
||||
<button
|
||||
onClick={() => scrollToSection(1)}
|
||||
className="mt-12 group flex items-center text-amber-600 font-bold hover:text-amber-800 transition-colors"
|
||||
>
|
||||
Next: Histograms{" "}
|
||||
<ArrowDown className="ml-2 w-5 h-5 group-hover:translate-y-1 transition-transform" />
|
||||
</button>
|
||||
</section>
|
||||
|
||||
{/* Section 2: Histograms */}
|
||||
<section
|
||||
ref={(el) => {
|
||||
sectionsRef.current[1] = el;
|
||||
}}
|
||||
className="min-h-screen flex flex-col justify-center mb-24"
|
||||
>
|
||||
<h2 className="text-4xl font-extrabold text-slate-900 mb-6">
|
||||
Histograms
|
||||
</h2>
|
||||
<div className="prose prose-slate text-lg text-slate-600 mb-8">
|
||||
<p>
|
||||
Histograms group data into <strong>bins</strong> (intervals). Each
|
||||
bar covers a range of values, and the height of the bar tells you
|
||||
how many data points fall in that range. All bins have equal width
|
||||
on the SAT.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-amber-50 border border-amber-200 rounded-2xl p-6 mb-8 space-y-4">
|
||||
<h3 className="text-lg font-bold text-amber-900">
|
||||
Key Histogram Concepts
|
||||
</h3>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div className="bg-white rounded-xl p-4 border border-amber-100">
|
||||
<p className="font-bold text-amber-800 mb-1">
|
||||
Frequency (Count)
|
||||
</p>
|
||||
<p className="text-slate-600 text-sm">
|
||||
The raw number of data points in a bin. Read directly from the
|
||||
y-axis when it is labeled "Frequency" or "Count".
|
||||
</p>
|
||||
</div>
|
||||
<div className="bg-white rounded-xl p-4 border border-amber-100">
|
||||
<p className="font-bold text-amber-800 mb-1">
|
||||
Relative Frequency (Percent)
|
||||
</p>
|
||||
<p className="text-slate-600 text-sm">
|
||||
Each bin's count divided by the total number of data points.
|
||||
Formula:{" "}
|
||||
<strong>
|
||||
Relative Frequency = <Frac n="count" d="total" />
|
||||
</strong>
|
||||
.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-amber-100 rounded-xl p-4">
|
||||
<p className="font-bold text-amber-900 mb-1">
|
||||
SAT Trick: Count vs. Percent Switch
|
||||
</p>
|
||||
<p className="text-slate-700 text-sm">
|
||||
The SAT frequently presents a histogram in one form (frequency)
|
||||
and asks a question that requires the other (relative
|
||||
frequency). Always check the y-axis label carefully.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<HistogramBuilderWidget />
|
||||
|
||||
<button
|
||||
onClick={() => scrollToSection(2)}
|
||||
className="mt-12 group flex items-center text-amber-600 font-bold hover:text-amber-800 transition-colors"
|
||||
>
|
||||
Next: Box Plots{" "}
|
||||
<ArrowDown className="ml-2 w-5 h-5 group-hover:translate-y-1 transition-transform" />
|
||||
</button>
|
||||
</section>
|
||||
|
||||
{/* Section 3: Box Plots */}
|
||||
<section
|
||||
ref={(el) => {
|
||||
sectionsRef.current[2] = el;
|
||||
}}
|
||||
className="min-h-screen flex flex-col justify-center mb-24"
|
||||
>
|
||||
<h2 className="text-4xl font-extrabold text-slate-900 mb-6">
|
||||
Anatomy of a Box Plot
|
||||
</h2>
|
||||
<div className="prose prose-slate text-lg text-slate-600 mb-8">
|
||||
<p>
|
||||
A Box Plot visualizes the <strong>5-Number Summary</strong>: Min,
|
||||
Q1, Median, Q3, Max. The box itself represents the{" "}
|
||||
<strong>IQR</strong> (Interquartile Range), which contains the
|
||||
middle 50% of the data.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-amber-50 border border-amber-200 rounded-2xl p-6 mb-8 space-y-4">
|
||||
<h3 className="text-lg font-bold text-amber-900">
|
||||
The 5-Number Summary
|
||||
</h3>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-5 gap-3">
|
||||
{[
|
||||
{ label: "Min", desc: "Smallest value (left whisker)" },
|
||||
{ label: "Q1", desc: "25th percentile (left edge of box)" },
|
||||
{ label: "Median", desc: "50th percentile (line inside box)" },
|
||||
{ label: "Q3", desc: "75th percentile (right edge of box)" },
|
||||
{ label: "Max", desc: "Largest value (right whisker)" },
|
||||
].map((item) => (
|
||||
<div
|
||||
key={item.label}
|
||||
className="bg-white rounded-xl p-3 border border-amber-100 text-center"
|
||||
>
|
||||
<p className="font-bold text-amber-800 text-lg">
|
||||
{item.label}
|
||||
</p>
|
||||
<p className="text-slate-500 text-xs mt-1">{item.desc}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="bg-white rounded-xl p-4 border border-amber-100">
|
||||
<p className="font-bold text-amber-800 mb-2">
|
||||
Interquartile Range (IQR)
|
||||
</p>
|
||||
<p className="text-slate-600 text-sm mb-2">
|
||||
The IQR measures the spread of the middle 50% of the data.
|
||||
</p>
|
||||
<p className="font-mono text-amber-700 font-bold">
|
||||
IQR = Q3 − Q1
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-amber-100 rounded-xl p-4">
|
||||
<p className="font-bold text-amber-900 mb-2">
|
||||
Outlier Detection Rule
|
||||
</p>
|
||||
<p className="text-slate-700 text-sm mb-2">
|
||||
A data point is an outlier if it falls outside these boundaries:
|
||||
</p>
|
||||
<div className="space-y-1 font-mono text-sm">
|
||||
<p className="text-red-700 font-bold">
|
||||
Lower Bound: Q1 − 1.5 × IQR
|
||||
</p>
|
||||
<p className="text-red-700 font-bold">
|
||||
Upper Bound: Q3 + 1.5 × IQR
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<BoxPlotAnatomyWidget />
|
||||
|
||||
<button
|
||||
onClick={() => scrollToSection(3)}
|
||||
className="mt-12 group flex items-center text-amber-600 font-bold hover:text-amber-800 transition-colors"
|
||||
>
|
||||
Next: Center & Spread{" "}
|
||||
<ArrowDown className="ml-2 w-5 h-5 group-hover:translate-y-1 transition-transform" />
|
||||
</button>
|
||||
</section>
|
||||
|
||||
{/* Section 4: Center & Spread (from CenterSpreadLesson) */}
|
||||
<section
|
||||
ref={(el) => {
|
||||
sectionsRef.current[3] = el;
|
||||
}}
|
||||
className="min-h-screen flex flex-col justify-center mb-24"
|
||||
>
|
||||
<h2 className="text-4xl font-extrabold text-slate-900 mb-6">
|
||||
Measures of Center & Spread
|
||||
</h2>
|
||||
<div className="prose prose-slate text-lg text-slate-600 mb-8">
|
||||
<p>
|
||||
The SAT always tests your ability to interpret center (where data
|
||||
clusters) and spread (how far data varies). Understanding what
|
||||
each measure is resistant or sensitive to is critical.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-amber-50 border border-amber-200 rounded-2xl p-6 mb-8 space-y-5">
|
||||
<h3 className="text-lg font-bold text-amber-900">
|
||||
Measures of Center
|
||||
</h3>
|
||||
|
||||
<div className="grid md:grid-cols-3 gap-4">
|
||||
<div className="bg-white rounded-xl p-4 border border-amber-200">
|
||||
<p className="font-bold text-amber-900 mb-1">Mean (Average)</p>
|
||||
<div className="font-mono text-center bg-amber-50 py-2 rounded text-amber-700 font-bold text-sm mb-2">
|
||||
<Frac n="Sum" d="Count" />
|
||||
</div>
|
||||
<p className="text-xs text-slate-600">
|
||||
Add all values, divide by how many there are. Sensitive to
|
||||
outliers — one extreme value pulls the mean.
|
||||
</p>
|
||||
</div>
|
||||
<div className="bg-white rounded-xl p-4 border border-amber-200">
|
||||
<p className="font-bold text-amber-900 mb-1">Median</p>
|
||||
<div className="font-mono text-center bg-amber-50 py-2 rounded text-amber-700 font-bold text-sm mb-2">
|
||||
Middle value (sorted)
|
||||
</div>
|
||||
<p className="text-xs text-slate-600">
|
||||
Sort the data. Middle value if odd count; average of middle
|
||||
two if even count. Resistant to outliers.
|
||||
</p>
|
||||
</div>
|
||||
<div className="bg-white rounded-xl p-4 border border-amber-200">
|
||||
<p className="font-bold text-amber-900 mb-1">Mode</p>
|
||||
<div className="font-mono text-center bg-amber-50 py-2 rounded text-amber-700 font-bold text-sm mb-2">
|
||||
Most frequent value
|
||||
</div>
|
||||
<p className="text-xs text-slate-600">
|
||||
The value that appears most often. A dataset can have no mode,
|
||||
one mode, or multiple modes. Rare on SAT.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-white rounded-xl p-5 border border-amber-100">
|
||||
<p className="font-bold text-amber-800 mb-3">
|
||||
Worked Example: Mean vs. Median with an Outlier
|
||||
</p>
|
||||
<div className="bg-amber-50 rounded-lg p-4 text-sm">
|
||||
<p className="font-semibold text-amber-800 mb-2">
|
||||
Dataset: {"{"}5, 7, 8, 9, 10, 11, 95{"}"}
|
||||
</p>
|
||||
<div className="font-mono text-xs text-slate-700 space-y-1">
|
||||
<p>Sum = 5 + 7 + 8 + 9 + 10 + 11 + 95 = 145</p>
|
||||
<p>
|
||||
Mean = <Frac n="145" d="7" /> ≈{" "}
|
||||
<strong className="text-rose-700">20.7</strong> ← pulled
|
||||
toward 95
|
||||
</p>
|
||||
<p>
|
||||
Median = <strong className="text-emerald-700">9</strong> ←
|
||||
middle value, not affected by 95
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 className="text-lg font-bold text-amber-900 pt-2">
|
||||
Measures of Spread
|
||||
</h3>
|
||||
|
||||
<div className="overflow-x-auto rounded-xl border border-amber-200">
|
||||
<table className="w-full text-sm border-collapse">
|
||||
<thead>
|
||||
<tr className="bg-amber-900 text-white">
|
||||
<th className="p-3 text-left">Measure</th>
|
||||
<th className="p-3 text-left">Formula</th>
|
||||
<th className="p-3 text-left">Sensitive to Outliers?</th>
|
||||
<th className="p-3 text-left">Best Used With</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-amber-100">
|
||||
<tr className="bg-white">
|
||||
<td className="p-3 font-bold">Range</td>
|
||||
<td className="p-3 font-mono text-amber-700">Max − Min</td>
|
||||
<td className="p-3 text-rose-700 font-bold">
|
||||
Yes — very sensitive
|
||||
</td>
|
||||
<td className="p-3 text-slate-600">Simple comparisons</td>
|
||||
</tr>
|
||||
<tr className="bg-amber-50">
|
||||
<td className="p-3 font-bold">IQR</td>
|
||||
<td className="p-3 font-mono text-amber-700">Q3 − Q1</td>
|
||||
<td className="p-3 text-emerald-700 font-bold">
|
||||
No — resistant
|
||||
</td>
|
||||
<td className="p-3 text-slate-600">Median; skewed data</td>
|
||||
</tr>
|
||||
<tr className="bg-white">
|
||||
<td className="p-3 font-bold">Standard Deviation</td>
|
||||
<td className="p-3 font-mono text-amber-700">
|
||||
Avg distance from mean
|
||||
</td>
|
||||
<td className="p-3 text-rose-700 font-bold">
|
||||
Yes — sensitive
|
||||
</td>
|
||||
<td className="p-3 text-slate-600">Mean; symmetric data</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div className="bg-white rounded-xl p-5 border border-amber-100">
|
||||
<p className="font-bold text-amber-800 mb-3">
|
||||
Skew Direction → Mean vs. Median
|
||||
</p>
|
||||
<div className="grid md:grid-cols-2 gap-3 text-sm">
|
||||
<div className="bg-rose-50 rounded-lg p-3 border border-rose-100">
|
||||
<p className="font-bold text-rose-800 mb-1">
|
||||
Right-Skewed (Positive Skew)
|
||||
</p>
|
||||
<p className="text-slate-700">
|
||||
A long tail extends to the right. Mean is pulled right
|
||||
(larger) by high outliers.
|
||||
</p>
|
||||
<p className="font-mono text-xs mt-1 text-rose-700">
|
||||
Mean > Median > Mode
|
||||
</p>
|
||||
</div>
|
||||
<div className="bg-blue-50 rounded-lg p-3 border border-blue-100">
|
||||
<p className="font-bold text-blue-800 mb-1">
|
||||
Left-Skewed (Negative Skew)
|
||||
</p>
|
||||
<p className="text-slate-700">
|
||||
A long tail extends to the left. Mean is pulled left
|
||||
(smaller) by low outliers.
|
||||
</p>
|
||||
<p className="font-mono text-xs mt-1 text-blue-700">
|
||||
Mean < Median < Mode
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button
|
||||
onClick={() => scrollToSection(4)}
|
||||
className="mt-4 group flex items-center text-amber-600 font-bold hover:text-amber-800 transition-colors"
|
||||
>
|
||||
Next: Effects of Change{" "}
|
||||
<ArrowDown className="ml-2 w-5 h-5 group-hover:translate-y-1 transition-transform" />
|
||||
</button>
|
||||
</section>
|
||||
|
||||
{/* Section 5: Effects of Data Changes (from CenterSpreadLesson) */}
|
||||
<section
|
||||
ref={(el) => {
|
||||
sectionsRef.current[4] = el;
|
||||
}}
|
||||
className="min-h-screen flex flex-col justify-center mb-24"
|
||||
>
|
||||
<h2 className="text-4xl font-extrabold text-slate-900 mb-6">
|
||||
Effects of Data Changes
|
||||
</h2>
|
||||
<div className="prose prose-slate text-lg text-slate-600 mb-8">
|
||||
<p>
|
||||
The SAT loves questions that ask what happens to mean, median, and
|
||||
standard deviation after modifying data — without making you
|
||||
recalculate everything. Memorize these rules.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-amber-50 border border-amber-200 rounded-2xl p-6 mb-8 space-y-5">
|
||||
<h3 className="text-lg font-bold text-amber-900">
|
||||
The Rules Table
|
||||
</h3>
|
||||
|
||||
<div className="overflow-x-auto rounded-xl border border-amber-200">
|
||||
<table className="w-full text-sm border-collapse">
|
||||
<thead>
|
||||
<tr className="bg-amber-900 text-white">
|
||||
<th className="p-3 text-left">Operation</th>
|
||||
<th className="p-3 text-left">Mean</th>
|
||||
<th className="p-3 text-left">Median</th>
|
||||
<th className="p-3 text-left">Std Dev / Range</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-amber-100">
|
||||
<tr className="bg-white">
|
||||
<td className="p-3 font-bold">
|
||||
Add constant k to every value
|
||||
</td>
|
||||
<td className="p-3 font-mono text-amber-700">Mean + k</td>
|
||||
<td className="p-3 font-mono text-amber-700">Median + k</td>
|
||||
<td className="p-3 font-bold text-emerald-700">
|
||||
No change
|
||||
</td>
|
||||
</tr>
|
||||
<tr className="bg-amber-50">
|
||||
<td className="p-3 font-bold">Multiply every value by k</td>
|
||||
<td className="p-3 font-mono text-amber-700">Mean × k</td>
|
||||
<td className="p-3 font-mono text-amber-700">Median × k</td>
|
||||
<td className="p-3 font-bold text-amber-700">
|
||||
× k (scales too)
|
||||
</td>
|
||||
</tr>
|
||||
<tr className="bg-white">
|
||||
<td className="p-3 font-bold">Add a high outlier</td>
|
||||
<td className="p-3 text-rose-700">Increases</td>
|
||||
<td className="p-3 text-emerald-700">Barely changes</td>
|
||||
<td className="p-3 text-rose-700">Increases</td>
|
||||
</tr>
|
||||
<tr className="bg-amber-50">
|
||||
<td className="p-3 font-bold">Remove a high outlier</td>
|
||||
<td className="p-3 text-rose-700">
|
||||
Decreases (toward center)
|
||||
</td>
|
||||
<td className="p-3 text-emerald-700">Barely changes</td>
|
||||
<td className="p-3 text-rose-700">Decreases</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div className="bg-white rounded-xl p-5 border border-amber-100">
|
||||
<p className="font-bold text-amber-800 mb-3">
|
||||
Why Adding k Doesn't Change Spread
|
||||
</p>
|
||||
<p className="text-sm text-slate-700 mb-2">
|
||||
Standard deviation measures how far values are from the mean. If
|
||||
you add k to every value, the mean also shifts by k — so every
|
||||
distance from the mean stays the same.
|
||||
</p>
|
||||
<div className="bg-amber-50 rounded-lg p-3 text-xs font-mono text-slate-700">
|
||||
<p>
|
||||
Dataset: {"{"}2, 4, 6{"}"} → Mean = 4, SD ≈ 1.63
|
||||
</p>
|
||||
<p>
|
||||
Add 10: {"{"}12, 14, 16{"}"} → Mean = 14, SD ≈ 1.63
|
||||
(unchanged)
|
||||
</p>
|
||||
<p>
|
||||
Multiply by 2: {"{"}4, 8, 12{"}"} → Mean = 8, SD ≈ 3.27
|
||||
(doubled)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
<div className="bg-sky-50 rounded-xl p-4 border border-sky-200 text-sm">
|
||||
<p className="font-semibold text-sky-800 mb-2">
|
||||
Worked Example 1: What happens when an outlier is removed?
|
||||
</p>
|
||||
<div className="font-mono text-xs text-slate-700 space-y-1">
|
||||
<p>
|
||||
Dataset: {"{"}2, 3, 4, 5, 6, 50{"}"}. Mean ≈ 11.7, Median =
|
||||
4.5
|
||||
</p>
|
||||
<p>
|
||||
Remove 50: {"{"}2, 3, 4, 5, 6{"}"}. Mean = 4, Median = 4
|
||||
</p>
|
||||
<p className="text-sky-800 font-bold">
|
||||
Mean decreased significantly. Median barely changed.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-sky-50 rounded-xl p-4 border border-sky-200 text-sm">
|
||||
<p className="font-semibold text-sky-800 mb-2">
|
||||
Worked Example 2: Scores shifted
|
||||
</p>
|
||||
<div className="font-mono text-xs text-slate-700 space-y-1">
|
||||
<p>Teacher adds 5 bonus points to every student's score.</p>
|
||||
<p>
|
||||
Class mean was 72 → new mean ={" "}
|
||||
<strong className="text-sky-800">77</strong>
|
||||
</p>
|
||||
<p>
|
||||
Class median was 74 → new median ={" "}
|
||||
<strong className="text-sky-800">79</strong>
|
||||
</p>
|
||||
<p>
|
||||
Standard deviation:{" "}
|
||||
<strong className="text-sky-800">no change</strong> (spread
|
||||
unchanged)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DataModifierWidget />
|
||||
|
||||
<button
|
||||
onClick={() => scrollToSection(5)}
|
||||
className="mt-12 group flex items-center text-amber-600 font-bold hover:text-amber-800 transition-colors"
|
||||
>
|
||||
Next: Comparisons{" "}
|
||||
<ArrowDown className="ml-2 w-5 h-5 group-hover:translate-y-1 transition-transform" />
|
||||
</button>
|
||||
</section>
|
||||
|
||||
{/* Section 6: Comparing Distributions */}
|
||||
<section
|
||||
ref={(el) => {
|
||||
sectionsRef.current[5] = el;
|
||||
}}
|
||||
className="min-h-screen flex flex-col justify-center mb-24"
|
||||
>
|
||||
<h2 className="text-4xl font-extrabold text-slate-900 mb-6">
|
||||
Comparing Distributions
|
||||
</h2>
|
||||
<div className="prose prose-slate text-lg text-slate-600 mb-8">
|
||||
<p>
|
||||
When comparing two datasets, always address two dimensions:{" "}
|
||||
<strong>Center</strong> and <strong>Spread</strong>. The SAT often
|
||||
asks you to compare groups using both.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="bg-amber-50 border border-amber-200 rounded-2xl p-6 mb-8 space-y-4">
|
||||
<h3 className="text-lg font-bold text-amber-900">
|
||||
What to Compare
|
||||
</h3>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div className="bg-white rounded-xl p-4 border border-amber-100">
|
||||
<p className="font-bold text-amber-800 mb-2">Center</p>
|
||||
<ul className="text-slate-600 text-sm space-y-1 list-disc list-inside">
|
||||
<li>
|
||||
<strong>Median</strong> — use when data is skewed or has
|
||||
outliers; it is resistant to extreme values.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Mean</strong> — use when data is roughly symmetric;
|
||||
it accounts for all values but is pulled by outliers.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="bg-white rounded-xl p-4 border border-amber-100">
|
||||
<p className="font-bold text-amber-800 mb-2">Spread</p>
|
||||
<ul className="text-slate-600 text-sm space-y-1 list-disc list-inside">
|
||||
<li>
|
||||
<strong>IQR</strong> — measures spread of the middle 50%;
|
||||
resistant to outliers. Preferred with median.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Standard Deviation (SD)</strong> — measures average
|
||||
distance from the mean; sensitive to outliers. Preferred
|
||||
with mean.
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-amber-100 rounded-xl p-4">
|
||||
<p className="font-bold text-amber-900 mb-1">
|
||||
SAT Language to Watch For
|
||||
</p>
|
||||
<p className="text-slate-700 text-sm">
|
||||
"Which group has greater variability?" → Compare IQR or SD
|
||||
(larger value = more spread out).
|
||||
<br />
|
||||
"Which group has a higher typical value?" → Compare medians
|
||||
or means.
|
||||
<br />
|
||||
"Are the distributions similar in shape?" → Look at whether
|
||||
both are symmetric, skewed left, or skewed right.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<BoxPlotComparisonWidget />
|
||||
|
||||
<button
|
||||
onClick={() => scrollToSection(6)}
|
||||
className="mt-12 group flex items-center text-amber-600 font-bold hover:text-amber-800 transition-colors"
|
||||
>
|
||||
Next: Practice Quiz{" "}
|
||||
<ArrowDown className="ml-2 w-5 h-5 group-hover:translate-y-1 transition-transform" />
|
||||
</button>
|
||||
</section>
|
||||
|
||||
{/* Section 7: Quiz */}
|
||||
<section
|
||||
ref={(el) => {
|
||||
sectionsRef.current[6] = el;
|
||||
}}
|
||||
className="min-h-screen flex flex-col justify-center"
|
||||
>
|
||||
<h2 className="text-4xl font-extrabold text-slate-900 mb-8">
|
||||
Practice Time
|
||||
</h2>
|
||||
{allQuizzes.map((quiz, idx) => (
|
||||
<div key={`quiz-${idx}`} className="mb-12">
|
||||
<Quiz data={quiz} />
|
||||
</div>
|
||||
))}
|
||||
<div className="p-8 bg-amber-900 rounded-2xl text-white text-center mt-12">
|
||||
<h3 className="text-2xl font-bold mb-4">Topic Mastered!</h3>
|
||||
<button
|
||||
onClick={onFinish}
|
||||
className="px-6 py-3 bg-white text-amber-900 font-bold rounded-full hover:bg-amber-50 transition-colors"
|
||||
>
|
||||
Finish Lesson ✓
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DataRepresentationLesson;
|
||||
Reference in New Issue
Block a user