Core Python and the full pandas workflow, from loading a CSV to exporting a transformed dataset, with visualisation in matplotlib and seaborn.
FizzBuzz, iterating 1 to 100 and branching on divisibility. Branch order carries the logic — the combined condition has to be tested first, or every multiple of 15 prints "fizz" because the first matching branch wins and the loop never reaches the rest.
Loading and inspection with read_csv, head, info and describe. Indexing and slicing, boolean filtering, derived columns, renaming and dropping. Aggregation with groupby and value_counts. Pivot tables. Grade banding with pd.cut. Sorting, and export with to_csv.
Running info() before any analysis surfaced a data quality problem immediately: 35 rows, but only 34 non-null name values, 34 non-null class values and 33 non-null gender values. Had the grouping been run first, the per-class and per-gender averages would have quietly excluded those rows with no indication at all.
Class means ranged from 82.57 down to 41.50 against a cohort mean of 74.66. But the lowest-scoring class has two students, and two classes ranking near the top have one student each. Reading the means alone would rank the classes. Reading them next to value_counts() shows that half the ranking rests on samples too small to support it.
Bar charts straight from a groupby, seaborn count plots, scatter plots, box plots with strip plot overlays, histograms with a mean reference line, and bar plots with 95% confidence intervals — because a mean without a spread makes noise look like signal.
The gender scatter plot was built after casting the column to string with astype(str). That converts NaN to the literal string "nan", so the two missing gender values became a third category and the chart rendered a nan column on the x-axis alongside female and male. The cast silenced the missing data rather than handling it.
The fix is to decide what the missing rows mean before casting — drop them with dropna, or label them explicitly with fillna. Missing data does not disappear when you stop looking at it, it just turns up somewhere less obvious.