AI Pathfinder (Ages 15-18)

Module 5 of 10

Module 05: Data Thinking

11 min read2,145 words
What you'll learn
Explain why data literacy matters for school, civics, and creative projects.Build a small pandas `DataFrame` from scratch and from a CSV (if available).Compute simple summaries: mean, median, min, max, counts, grouped averages.Create matplotlib charts (line, bar) with titles and axis labels that respect the reader.Spot misleading charts and missing context (axis tricks, tiny samples, cherry-picking).Complete a personal data story mini-project you could show in a portfolio or class.

You already generate data every day: steps, screen time, likes, sleep guesses, practice hours. Most people let it evaporate. You are going to learn to catch a little of it, organize it honestly, and show it clearly—because in 2026, “trust me” lost to “here is the chart” in almost every serious conversation.

No gatekeeping: You do not need to be a statistician to think like a data person. You need curiosity, labels that make sense, and the humility to say, “I could be reading this wrong—let’s check.”

Time & tools: Budget ~90 minutes for first read + notebook setup, then spread plotting and writing across several short sessions—your eyes spot chart lies better when you sleep between passes.

What if math makes me nervous? You are allowed to use calculators and pandas helpers. The goal is thinking, not mental arithmetic Olympics.

Learning Objectives

By the end of this module, you will be able to:

  • Explain why data literacy matters for school, civics, and creative projects.
  • Build a small pandas DataFrame from scratch and from a CSV (if available).
  • Compute simple summaries: mean, median, min, max, counts, grouped averages.
  • Create matplotlib charts (line, bar) with titles and axis labels that respect the reader.
  • Spot misleading charts and missing context (axis tricks, tiny samples, cherry-picking).
  • Complete a personal data story mini-project you could show in a portfolio or class.

1. Data Is a Story With Receipts

Data = structured information you can aggregate. Thinking = asking what was measured, how, and what is missing.

QuestionWhy it matters
Who collected it?Incentives & bias
What was measured?Definitions change outcomes
When was it collected?Old data on fast topics misleads
How big is the sample?N=3 is a vibe, not a population
What’s missing?Silence is a signal

Did You Know? “Average” can mean mean or median—they diverge when outliers exist (think billionaire in a room of students).

Try-it: Find one stat in your social feed this week. Answer the five questions above in bullets—even if answers are “unknown.” Unknown is useful data.

2. From Messy Notes to a DataFrame (pandas)

Install (if local): pip install pandas matplotlib

In Colab, these are often preinstalled.

python
[object Object], pandas ,[object Object], pd

,[object Object],
data = {
    ,[object Object],: [,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],],
    ,[object Object],: [,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],],
    ,[object Object],: [,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],],
    ,[object Object],: [,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],],
    ,[object Object],: [,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],],
}

df = pd.DataFrame(data)
,[object Object],(df)

,[object Object],
,[object Object],(df.dtypes)
,[object Object],(df.describe())  ,[object Object],

Fun Fact: describe() is your first dashboard—lazy in the best way.

Activity: Replace numbers with your real week (rough estimates are OK if labeled as estimates).

3. Selecting Columns and Basic Math

python
[object Object],
study_hours = df[,[object Object],]

,[object Object],
avg_study = df[,[object Object],].mean()
avg_social = df[,[object Object],].mean()

,[object Object],(,[object Object],)
,[object Object],(,[object Object],)

,[object Object],
df[,[object Object],] = df[,[object Object],] + df[,[object Object],]
,[object Object],(df[[,[object Object],, ,[object Object],, ,[object Object],]])

Try-it: Add a column Sleep (h) (guess ok). Which day has max study?

python
[object Object],
,[object Object],
,[object Object],

Did You Know? Defining a metric is a creative act. “Screen time” can mean five different things—define yours so you do not fool yourself.

4. Sorting, Filtering, Group-By Light

python
[object Object],
sorted_by_mood = df.sort_values(,[object Object],, ascending=,[object Object],)
,[object Object],(sorted_by_mood[[,[object Object],, ,[object Object],, ,[object Object],]])

,[object Object],
heavy_study = df[df[,[object Object],] >= ,[object Object],]
,[object Object],(,[object Object],)
,[object Object],(heavy_study)

,[object Object],
corr = df[[,[object Object],, ,[object Object],, ,[object Object],]].corr()
,[object Object],(corr)

Mentor warning: Correlation is not causation. Bad sleep, tough classes, and social time can tangle together.

5. Visualization: Make the Chart Earn Its Space

python
[object Object], matplotlib.pyplot ,[object Object], plt

,[object Object],
fig, ax = plt.subplots(figsize=(,[object Object],, ,[object Object],))
ax.plot(df[,[object Object],], df[,[object Object],], marker=,[object Object],, label=,[object Object],)
ax.plot(df[,[object Object],], df[,[object Object],], marker=,[object Object],, label=,[object Object],)
ax.set_title(,[object Object],)
ax.set_xlabel(,[object Object],)
ax.set_ylabel(,[object Object],)
ax.legend()
ax.grid(,[object Object],, alpha=,[object Object],)
plt.tight_layout()
plt.show()
python
[object Object],
fig, ax = plt.subplots(figsize=(,[object Object],, ,[object Object],))
df.plot(
    x=,[object Object],,
    y=[,[object Object],, ,[object Object],, ,[object Object],],
    kind=,[object Object],,
    ax=ax,
)
ax.set_title(,[object Object],)
ax.set_ylabel(,[object Object],)
plt.tight_layout()
plt.show()

Fun Fact: Defaults are fine for learning; labels are what separate “pretty” from honest.

Checklist before you share a chart:

  • Title states what and when
  • Axes have units
  • Source noted if external data

6. Reading Charts in the Wild (Defense Against Trickery)

TrickWhat to do
Y-axis not starting at 0Ask if differences are tiny but look huge
Cherry-picked datesZoom out—what happens on wider timeline?
Pretty map without ratesRaw counts favor big populations
Percent without base“50% increase” from 2→3 is not like 2M→3M story

Try-it: Find a chart in a news article. List two honest improvements the editor could make.

7. Optional: Load a CSV (If You Have One)

python
[object Object],
,[object Object],
,[object Object],

If files are annoying right now, skip—dictionaries already make you legit.

8. Mean vs Median: When “Average” Lies

python
[object Object],
sleep_hours = [,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],]
s = pd.Series(sleep_hours)
,[object Object],(,[object Object],, s.mean())
,[object Object],(,[object Object],, s.median())

Did You Know? News articles love mean income; labor economists often prefer median—it resists a few giant outliers.

Try-it: Add your own outlier list (grades, prices). Compare mean vs median in two sentences of interpretation.

9. Data Ethics in One Module (Preview)

Even personal data projects deserve care:

  • Consent: If you track friends, ask.
  • Sharing: Blur identifying details in public posts.
  • Honesty: Label estimates as estimates.

Fun Fact: The most impressive student projects say limitations out loud—that is scientific maturity.

10. Presentation Hacks for Class (No Design Degree Needed)

  • One main claim per slide.
  • Chart full screen, text minimal.
  • Say “Here is what surprised me”—teachers are human; curiosity hooks them.

Pair activity: Trade charts with a partner for 60 seconds of “hard questions.” Revise once.

Activities

  1. Track a week: Real or estimated data—build df, compute means, highlight best/worst day.
  2. New chart type: Try kind="barh" horizontal bars for the same data—which reads easier for you?
  3. Summary paragraph: Write five sentences interpreting your plots—no numbers in sentence one (forces story, not spam).
  4. Bias check: What would a skeptical friend say about your definitions? Add a footnote in markdown.
  5. Mini comparison: Two weeks side by side (copy dataframe, change values)—percent change in study hours.
  6. Ethics: Would you post this chart publicly? Why/why not?

Practice Challenges

  1. Mood histogram: Use the Mood (1-5) column (or your own ratings) to build a histogram with matplotlib—see section 11 below for starter code. Write two sentences: what shape do you see, and what would you need before claiming "I am usually a 4"?

  2. Category counts: Invent a tiny DataFrame of club attendance (name + event). Use value_counts() to find who showed up most. Explain one limitation of that metric (example: small sample size).

  3. Truthful vs. flashy bar: Plot the same weekly data twice—once with y-axis starting at 0, once truncated to make differences look huge. In one paragraph, explain which chart you would submit to a teacher and why.

  4. CSV reality check: If you can export your own grades or practice log as CSV, load it with pd.read_csv, print head(), and compute one summary stat you care about. If you cannot use a real file, use a public dataset from your city’s open-data portal.

  5. Correlation journal: Run .corr() on three numeric columns you tracked. Pick one cell in the matrix and interpret it in plain language—then add one sentence about what could confuse cause and effect.

Your Challenge

“My Data Story” (portfolio-worthy)

  • Collect at least 7 days of one metric you care about (sleep, practice, mood, steps, reading minutes…).
  • Build a pandas DataFrame, compute at least three statistics (mean, max, standard deviation).
  • Make two matplotlib visuals with proper title + axis labels.
  • Write half a page with three claims supported by your tables/plots—and one claim you reject after looking closer (intellectual honesty for the win).

Stretch: Export chart to PNG and embed in a short Google Slides deck—practice presenting data, not only coding it.

Key Takeaways

  • Data thinking starts with definitions and context.
  • pandas makes tabular work fast once you speak its columns.
  • matplotlib turns numbers into shared sight.
  • Correlation ≠ causation—repeat it until boring; then repeat again.
  • Ethical charts label and cite; sketchy charts dazzle and hide.
  • Your own life data is a sandbox—low stakes, real skills.

Going Further

  • Seaborn for prettier statistical plots (next step after matplotlib comfort).
  • Open data portals (city/county/government) for civic projects.
  • Module 06: Automate gathering CSVs (ethically).
  • Kaggle Learn micro-courses if you want gamified drills—stay mindful of time boxes.
  • Storytelling: Read one article from Our World in Data or similar—notice chart choices, not only conclusions.

Quick Reference — Chart Check Before Submit

Title? Units? Source? Sample definition? Surprises acknowledged? Five checks—if you can answer aloud, you are ready.

Partner Lab — “Lie With Statistics” (Ethical Edition)

In pairs, intentionally make a slightly misleading chart (truncated axis, etc.), then fix it together. Discuss how honesty changes the story. Destroy the misleading version after—this is training, not propaganda practice.

Notebook Hygiene

Name notebooks with dates (2026-04-01_screen_time_v2.ipynb), keep a top cell with goals, and restart kernel + run all before claiming “it works.” Future you sends thanks.

Data You Already Own: Social, Gaming, Music

Spotify / Apple Music “Wrapped” is a product telling a story with your clicks. Ask: who chose the categories? What was left out (songs you skipped after 1 second)? Why does “top genre” feel so right—because it is true, or because it is flattering?

Gaming dashboards: K/D, rank, hours—easy to plot. Before you flex a chart in Discord, label it “one account, one season” so nobody thinks you sampled the whole player base.

School gradebooks export: If you can download CSV, you can pandas it—only for your rows unless everyone consents to a group project analysis.

python
[object Object],
,[object Object],

,[object Object], pandas ,[object Object], pd

matches = pd.DataFrame(
    {
        ,[object Object],: [,[object Object],, ,[object Object],, ,[object Object],],
        ,[object Object],: [,[object Object],, ,[object Object],, ,[object Object],],
        ,[object Object],: [,[object Object],, ,[object Object],, ,[object Object],],
    }
)
,[object Object],(matches.groupby(,[object Object],)[,[object Object],].mean())

Did You Know? Game companies run A/B tests on millions of players—your “personal” difficulty curve might be a experiment arm. That is not evil automatically; it is a reason to read patch notes and privacy policies when you care.

Activity — lyric length analysis (ethical): Type out one verse of a public domain song or your own lyrics (not copyrighted paste from Genius). Use Python len, word counts, or pandas—one chart. Lesson: even tiny text data teaches tokenization intuition for later AI modules.

Activity — “influencer chart audit”: Screenshot one creator’s analytics-style graphic (engagement up!). List two missing context questions: time range? paid promotion? purchased followers? Practice skepticism without cynicism.

Challenge — sleep vs. mood (honest science): Track 7 days sleep + mood (1–5). Plot both lines. In your write-up, acknowledge confounders (exam week, drama, caffeine). Pro move: one paragraph “what I still cannot conclude.”

Pro Tip: When presenting to class, lead with the surprise, not the methodology—then show the chart that earned the surprise.

11. Histograms, value_counts, and Group-By (More Python, Same Honesty)

Sometimes you do not need a time series—you want how often something happened. Histograms bucket numeric data so you can see the shape of a week (mood spikes, study hours clumped around two hours, etc.). value_counts() does the same idea for categories (which subject shows up most in your log, which friend won most chess games—with consent).

python
[object Object], pandas ,[object Object], pd
,[object Object], matplotlib.pyplot ,[object Object], plt

,[object Object],
demo = pd.DataFrame(
    {
        ,[object Object],: [,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],],
        ,[object Object],: [,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],],
        ,[object Object],: [,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],],
    }
)

,[object Object],
,[object Object],
counts = demo[,[object Object],].value_counts()
,[object Object],(,[object Object],, counts)

,[object Object],
,[object Object],
by_subject = demo.groupby(,[object Object],)[,[object Object],].mean().sort_values(ascending=,[object Object],)
,[object Object],(,[object Object],, by_subject)

,[object Object],
,[object Object],
fig, ax = plt.subplots(figsize=(,[object Object],, ,[object Object],))
ax.hist(demo[,[object Object],], bins=,[object Object],(,[object Object],, ,[object Object],), align=,[object Object],, rwidth=,[object Object],, color=,[object Object],)
ax.set_title(,[object Object],)
ax.set_xlabel(,[object Object],)
ax.set_ylabel(,[object Object],)
ax.set_xticks([,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],])
ax.grid(,[object Object],, axis=,[object Object],, alpha=,[object Object],)
plt.tight_layout()
plt.show()

Did You Know? Choosing bin width for a histogram changes the story. Too few bins hides detail; too many looks noisy. For 1–5 mood scores, discrete bins (like above) keep the chart honest.

Try-it: Replace demo with your week. Add a one-sentence caption under your chart: "Limitations:" (sample size, estimates, what you did not measure).

Mentor note: If your histogram is one bar—you only tracked one day. That is not failure; it is a reminder to collect more rows before you give a speech about "my typical week."

12. Rolling Averages and "Smoothing" the Noise (Python)

One wild Friday can make a line chart look like a heart attack. A rolling mean (moving average) averages each day with a window of neighbors so you see trend without erasing raw data.

python
[object Object], pandas ,[object Object], pd
,[object Object], matplotlib.pyplot ,[object Object], plt

,[object Object],
week = pd.DataFrame(
    {
        ,[object Object],: [,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],],
        ,[object Object],: [,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object],],
    }
)

,[object Object],
week[,[object Object],] = week[,[object Object],].rolling(window=,[object Object],, min_periods=,[object Object],).mean()

fig, ax = plt.subplots(figsize=(,[object Object],, ,[object Object],))
ax.plot(week[,[object Object],], week[,[object Object],], marker=,[object Object],, label=,[object Object],)
ax.plot(week[,[object Object],], week[,[object Object],], marker=,[object Object],, label=,[object Object],)
ax.set_title(,[object Object],)
ax.set_ylabel(,[object Object],)
ax.legend()
ax.grid(,[object Object],, alpha=,[object Object],)
plt.tight_layout()
plt.show()

Did You Know? Smoothing is a choice—it can hide important spikes (panic study nights). Ethical practice: show raw and smoothed, or caption exactly what you did.

Try-it: Change window to 2 and 5. Which window feels honest for your week—and which feels like lying by makeup?

Activity — two-chart story: Plot raw mood and 3-day rolling mood side by side. Write three sentences: when smoothing helped truth, when it hid truth.

13. Percent Change Week Over Week (Honest Comparisons)

python
[object Object], pandas ,[object Object], pd

a = pd.DataFrame({,[object Object],: [,[object Object],, ,[object Object],, ,[object Object],]})  ,[object Object],
b = pd.DataFrame({,[object Object],: [,[object Object],, ,[object Object],, ,[object Object],]})  ,[object Object],

mean_a, mean_b = a[,[object Object],].mean(), b[,[object Object],].mean()
pct = (mean_b - mean_a) / mean_a * ,[object Object],
,[object Object],(,[object Object],)

Pro Tip: Percent change from tiny baselines explodes ("200% more" from 0.5h → 1.5h). Pair percent with absolute hours in captions.

Challenge — define the denominator: Before you brag "I studied 40% more," write one sentence: 40% more than what baseline week? If you cannot name it, wait.

More Activities and Challenges

Activity — classroom data etiquette: List three numbers you could ethically collect in a group survey (favorite snack) vs three you should not collect without safeguards (mental health details). Discuss why.

Activity — chart caption contest: Swap charts with a partner. Each writes a title that is true but boring and one that is flashy but misleading. Vote on which to never use in a school paper.

Practice challenge — merge two weeks: pd.concat two weekly tables, reset index, plot cumulative study hours. Where did the semester feel hard vs where the data says it was hard?

Practice challenge — missing data diary: For three days, note one hour where you forgot to log. Impute nothing—instead, add a column missing_flag. Discuss with a mentor: when is honest gap better than fake precision?

Comparison — which summary for which story?

StatisticTells a good story when…Fails when…
MeanValues are fairly symmetricOutliers dominate (one all-nighter)
MedianA few extremes skew the pictureYou need total load, not "typical"
MaxPeak performance mattersYou imply every day looked like peak

Numbers do not speak for themselves—you speak with them. Make sure they are telling the truth.