Rohit and Virat both played five one-day matches this season. Here are their scores:
- Rohit: 45, 62, 38, 55, 50
- Virat: 20, 15, 200, 18, 12
Add up Rohit's runs and you get 250; divide by 5 matches and his average is 50 runs per innings. Add up Virat's runs — 20 + 15 + 200 + 18 + 12 — and you get 265; divide by 5 and his average is 53 runs per innings. By this single number, Virat looks like the slightly better batsman. But look again at the actual scores. Virat got out for under 21 runs in four of his five innings, and only once, in a single freak innings, did he score 200. Rohit, on the other hand, batted consistently — never below 38, never above 62. If you were a team selector picking a batsman you could rely on match after match, would you really call Virat the better choice just because his "average" is 3 runs higher?
This is exactly the kind of question statistics is built to answer — not just "what is the average" but "what actually describes this data well, and what doesn't." Statistics is the branch of mathematics (and, for us, of computing) concerned with collecting numbers, organizing them, summarizing them into meaningful measures, and knowing which summary to trust. A dataset of raw numbers — 265 runs across 5 unsorted innings — tells you almost nothing on its own. Statistics turns that raw pile of numbers into insight. And because real datasets in the world are never five numbers long — they're thousands or millions of rows — the real skill you're learning in this chapter is not just "how to compute an average by hand," but how to write small, correct algorithms that compute these summaries for you, and how to reason about when each summary is honest and when it's misleading.
The Mean: Adding and Sharing Equally
The most familiar statistical measure is the mean, which is what most people casually call "the average." The idea behind the mean is simple: imagine taking all the runs Rohit scored across his five innings and redistributing them equally, as if every innings had gone exactly the same. The formula is:
mean = (sum of all values) / (number of values)
For Rohit: (45 + 62 + 38 + 55 + 50) / 5 = 250 / 5 = 50. On average, across the season, Rohit scored 50 runs per innings. This is a genuinely useful number when the data doesn't have extreme values pulling it around — notice that 50 sits right in the middle of Rohit's actual scores (38 to 62), so it does represent his "typical" innings reasonably well.
In code, computing a mean over a list is one line, because Python already gives you the two ingredients you need — a way to add up a list (sum()) and a way to count its length (len()):
scores = [45, 62, 38, 55, 50]
mean = sum(scores) / len(scores)
print(mean) # 50.0
Trace through it: sum(scores) adds 45 + 62 + 38 + 55 + 50 to get 250. len(scores) counts 5 items. Python divides 250 by 5 using true division (the single /, not //), which always returns a decimal number, giving 50.0. This matters for correctness: if you used // (integer division) instead, a mean like 265/5 would still work fine (=53), but a mean like 21/4 would silently give you 5 instead of the correct 5.25, throwing away the fractional part. Always use / for a mean.
When the Mean Lies: Meet the Median
Common misconception: many students treat "average" and "typical value" as the same thing — believing that whatever the mean comes out to be must represent a normal, ordinary case in the data. Virat's batting average proves this wrong. His mean is 53, yet he never actually scored anywhere near 53 in four of his five innings — he scored far below it every time except the one match where he scored far above it. The mean of 53 is not "typical" of anything; it's an artifact of one enormous number dragging the average upward. A single unusually large (or small) value in a dataset is called an outlier, and the mean is extremely sensitive to outliers, because every value — including the outlier — gets added into the sum before dividing.
This is where a second measure, the median, becomes essential. The median is the middle value of a dataset once it has been sorted from smallest to largest. Unlike the mean, the median doesn't care how large or small the extreme values are — it only cares about their position after sorting. Let's find Virat's median by hand:
- Sort the scores: 12, 15, 18, 20, 200.
- Count how many values there are: 5 (an odd number).
- Since there are 5 values, the middle one is the 3rd value: 18.
Virat's median score is 18 — a much more honest description of what he typically scored than the mean of 53. Compare this to Rohit's median: sorted, his scores are 38, 45, 50, 55, 62, and the middle (3rd) value is 50 — exactly the same as his mean, because Rohit's data has no outlier dragging things around. This comparison is the real lesson: when the mean and median are close together, the data is fairly evenly spread and the mean is trustworthy; when they're far apart, an outlier is distorting the mean, and the median is the more honest summary.
Finding the middle position gets one extra step trickier when the dataset has an even number of values, because there is no single middle item — there are two, and you average them. For example, if Rohit had played only 4 matches — 38, 45, 50, 55 — there is no single middle value; positions 2 and 3 (45 and 50) are both "in the middle," so the median is their mean: (45 + 50) / 2 = 47.5.
Writing a correct median function requires two ingredients an average function doesn't need: sorting the data first (median is meaningless on unsorted data — you cannot pick "the middle" of a jumbled list), and a branch that handles the odd-length and even-length cases differently:
def median(data):
data = sorted(data)
n = len(data)
mid = n // 2
if n % 2 == 1:
return data[mid]
else:
return (data[mid - 1] + data[mid]) / 2
print(median([20, 15, 200, 18, 12])) # 18
print(median([38, 45, 50, 55])) # 47.5
Trace the first call carefully. sorted([20, 15, 200, 18, 12]) produces [12, 15, 18, 20, 200]. Its length n is 5, so mid = 5 // 2 = 2 (integer division, so it rounds down). Since 5 % 2 == 1 (5 is odd), the function returns data[2]. Remember Python indexes from 0, so data[2] is the third item in the list — 18. Correct.
Now the second call: sorted([38, 45, 50, 55]) is already sorted. n = 4, so mid = 4 // 2 = 2. Since 4 % 2 == 0 (4 is even), we go to the else branch and compute (data[1] + data[2]) / 2. data[1] is the 2nd item, 45; data[2] is the 3rd item, 50. So the result is (45 + 50) / 2 = 47.5. This matches what we calculated by hand.
The diagram below plots Virat's five scores on a number line and marks both the mean and the median, so you can see the gap between them at a glance.
Notice how the four ordinary scores sit bunched together near the left, and the median line lands right on top of the "18" dot — because 18 genuinely is the middle score. The mean, by contrast, sits far to the right of the entire cluster, in a region where Virat almost never actually scored. It only ends up there because the single outlier (200) is heavy enough to pull the sum — and therefore the average — a long way to the right, even though it's only one out of five data points.
The Mode: What Occurs Most Often
Mean and median both need numeric data you can add and sort. But sometimes the data you collect isn't naturally numeric — for example, survey answers. Suppose you ask 15 classmates their favourite subject, and record their answers as a list:
subjects = ["Math", "Science", "English", "Math", "Hindi",
"Math", "Science", "English", "Math", "SST",
"Science", "English", "Hindi", "Math", "Science"]
You can't take a "mean" of subject names — "Math" plus "Science" divided by two is meaningless. What you want instead is the mode: the value that occurs most frequently in the data. To find it, you count how many times each distinct value appears, then pick the one with the highest count. In code, a dictionary is the natural tool for counting, because it lets you map each subject name to a running total:
counts = {}
for subject in subjects:
counts[subject] = counts.get(subject, 0) + 1
print(counts)
# {'Math': 5, 'Science': 4, 'English': 3, 'Hindi': 2, 'SST': 1}
mode = max(counts, key=counts.get)
print(mode) # Math
Trace this loop step by step. counts starts empty. For each subject in the list, counts.get(subject, 0) looks up the subject's current count — returning 0 if it isn't in the dictionary yet — and we add 1 to it, storing the result back. Walking through the first few items: "Math" isn't in counts yet, so counts.get("Math", 0) is 0, and counts["Math"] becomes 1. Next, "Science" becomes 1. Next, "English" becomes 1. Next, "Math" appears again — now counts.get("Math", 0) returns 1 (the value we stored last time), and counts["Math"] becomes 2. This continues for all 15 items. By the end, Math has appeared 5 times, Science 4 times, English 3 times, Hindi 2 times, and SST once — 5 + 4 + 3 + 2 + 1 = 15, matching the length of the original list, which is a good sanity check that no items were missed.
The last line, max(counts, key=counts.get), finds the dictionary key whose associated value (via counts.get) is largest — that's "Math," with 5 votes, so it is the mode. Unlike mean and median, a dataset can have more than one mode (if two values are tied for the highest count, both are modes — this is called "bimodal" data), or no meaningful mode at all if every value appears exactly once, which we'll see in a moment.
Range: How Spread Out Is the Data?
Mean, median, and mode all try to describe a single "central" or "typical" value. But two datasets can have the exact same mean and still look completely different in how spread out they are. The simplest measure of spread is the range: the difference between the largest and smallest value.
range = max(data) - min(data)
For Rohit's scores (38, 45, 50, 55, 62), the range is 62 − 38 = 24 — a tight, consistent spread. For Virat's scores (12, 15, 18, 20, 200), the range is 200 − 12 = 188 — an enormous spread, even though his mean (53) isn't dramatically different from Rohit's mean (50). This is exactly the extra piece of information that "average" alone hides: two batsmen can average almost the same runs while one is dependably consistent and the other is wildly unpredictable. A good statistical summary of a dataset almost always reports both a measure of center (mean/median/mode) and a measure of spread (range, or more advanced measures you'll meet in later grades, like standard deviation) — center alone is an incomplete picture.
Organizing Raw Data: Frequency Distribution Tables
Five or fifteen values, you can eyeball. But real datasets — marks of an entire class, attendance across a term, sensor readings from a device — can run into hundreds or thousands of values, far too many to stare at as a flat list. The standard technique is to group the values into equal-sized ranges called class intervals, and count how many data points fall into each range. This grouped count is a frequency distribution table.
Suppose 20 students take a test out of 100 marks, and the raw scores are:
marks = [55, 78, 62, 45, 90, 33, 71, 58, 82, 49,
67, 91, 38, 74, 56, 63, 85, 42, 77, 60]
Grouping these into intervals of width 20 (0–20, 20–40, 40–60, 60–80, 80–100, where each interval includes its lower bound but not its upper bound) and counting how many marks fall in each gives:
- 0–20: 0 students
- 20–40: 2 students (33, 38)
- 40–60: 6 students (45, 49, 55, 56, 58, 42)
- 60–80: 8 students (60, 62, 63, 67, 71, 74, 77, 78)
- 80–100: 4 students (82, 85, 90, 91)
Check: 0 + 2 + 6 + 8 + 4 = 20, which matches the total number of students — a check you should always run after building a frequency table, since a miscount here silently corrupts every later calculation. Now the shape of the class's performance is instantly visible without reading 20 individual numbers: most students clustered in the 60–80 range, a healthy number scored well (80–100), and only a couple struggled badly (20–40). This is precisely the data that would be drawn as a bar graph or histogram, with each bar's height equal to the frequency count — the frequency table is the numeric preparation step that has to happen correctly before any chart can be trusted.
Choosing the Right Measure
A frequent exam mistake is treating "mean," "median," and "mode" as three interchangeable ways to compute the same "average," when in fact each one answers a different question and each has situations where it clearly performs best:
- Mean is the right choice when every value should count and the data has no severe outliers — for example, average rainfall across normal months, or average marks in a fair, evenly-scored test.
- Median is the right choice when outliers or a skewed shape could distort a straightforward average — for example, "typical" household income (a few very high incomes can massively distort the mean while barely touching the median), or a "typical" delivery time when one order got delayed for an unusual reason.
- Mode is the right choice for categorical, non-numeric data (favourite subject, most common blood group in a class, most frequently bought size of shoe in a shop) where mean and median don't even make mathematical sense — you can't average shoe sizes labeled "M" and "L."
A useful habit is to compute mean and median together whenever you can, purely as a diagnostic: if they're close, the data is well-behaved and either is safe to quote; if they're far apart, that gap itself is telling you there's an outlier or a skew worth investigating before you trust any single number.
Putting It Together: One Complete Program
Let's now write a single program that computes all four measures — mean, median, mode, and range — on the 20-student marks dataset from the frequency table above, and see what each one tells us.
marks = [55, 78, 62, 45, 90, 33, 71, 58, 82, 49,
67, 91, 38, 74, 56, 63, 85, 42, 77, 60]
def mean(data):
return sum(data) / len(data)
def median(data):
data = sorted(data)
n = len(data)
mid = n // 2
if n % 2 == 1:
return data[mid]
return (data[mid - 1] + data[mid]) / 2
def data_range(data):
return max(data) - min(data)
print("Mean: ", mean(marks))
print("Median:", median(marks))
print("Range: ", data_range(marks))
Trace the mean: summing all 20 marks gives 1276, and 1276 / 20 = 63.8. Trace the median: sorting the 20 marks gives [33, 38, 42, 45, 49, 55, 56, 58, 60, 62, 63, 67, 71, 74, 77, 78, 82, 85, 90, 91]. Since n = 20 is even, mid = 20 // 2 = 10, and we average data[9] and data[10] — the 10th and 11th values in the sorted list, which are 62 and 63. So the median is (62 + 63) / 2 = 62.5. Trace the range: the largest mark is 91, the smallest is 33, so the range is 91 − 33 = 58.
Notice that mean (63.8) and median (62.5) come out very close to each other here — less than 1.3 apart. By the diagnostic habit from the previous section, that closeness tells you this dataset doesn't have a severe outlier distorting things; either number is a fair summary of "how the class did." Now try computing the mode on these same 20 marks: every single value in the list is different — no mark repeats. In that case, there is no mode at all, or every value is "equally the mode," which really means the concept of mode is not useful here. This is an important, often-skipped lesson: mode works well for data with natural repeats (survey categories, dice rolls, grades like A/B/C), but for continuous, fine-grained measurements like exact marks out of 100, values rarely repeat by chance, and forcing a mode calculation on them produces a meaningless or empty answer. Recognizing when a statistical tool doesn't apply is as important as knowing how to compute it.
Test Yourself
Work through each question before checking the answer.
Q1. A small dataset is [4, 8, 6, 5, 3, 2, 8, 9, 8]. Find the mean, median, and mode.
Sum = 4+8+6+5+3+2+8+9+8 = 53, and there are 9 values, so mean = 53 / 9 ≈ 5.89. Sorted: [2, 3, 4, 5, 6, 8, 8, 8, 9] — 9 values (odd), so the median is the 5th value (index 4): 6. The value 8 appears three times, more than any other value, so the mode is 8.
Q2. Suppose five families report monthly incomes (in thousands of rupees) of 25, 28, 30, 27, and 500 — the last family runs a business with an unusually high income that month. Which measure, mean or median, better describes a "typical" family's income here, and why?
Mean = (25+28+30+27+500) / 5 = 610 / 5 = 122 thousand rupees. Median (sorted: 25, 27, 28, 30, 500 — middle value) = 28 thousand rupees. The mean of ₹1,22,000 doesn't describe any of the four ordinary families at all — it's dragged upward entirely by the one outlier. The median of ₹28,000 is a far more honest description of what a "typical" family in this group earns. This is exactly why real-world income statistics are usually reported as medians, not means.
Q3. True or False: "The mean of a dataset is always one of the values that appears in the dataset." Justify your answer with an example.
False. For the dataset [1, 2, 4], the mean is (1+2+4)/3 = 7/3 ≈ 2.33, and 2.33 doesn't appear anywhere in the original list. The mean is a computed value, not a value picked from the data — unlike the median (for odd-length lists) or the mode, which are always actual data values.
Q4. Write, in your own words, what change you would need to make to the median() function shown earlier if the list could contain duplicate values (for example, [10, 10, 20, 30]). Would it still work correctly without any change?
No change is needed — the function already works correctly with duplicates, because sorted() keeps repeated values next to each other and the position-counting logic (n // 2, odd/even check) only cares about position in the sorted order, not whether values repeat. For [10, 10, 20, 30]: sorted is unchanged, n=4 (even), mid=2, median = (data[1] + data[2]) / 2 = (10 + 20) / 2 = 15.
Summary
- Statistics is the discipline of collecting raw data and computing summary measures that reveal patterns a flat list of numbers hides.
- Mean = sum of values ÷ count of values. Sensitive to outliers — one extreme value can shift it far from what's "typical."
- Median = the middle value of sorted data (average of the two middle values if the count is even). Resistant to outliers, making it the better choice for skewed data.
- Mode = the most frequently occurring value. The only sensible measure of "center" for categorical (non-numeric) data, and often or meaningless when every value in a numeric dataset is distinct.
- Range = maximum − minimum. A first measure of how spread out a dataset is, and essential alongside a center measure — two datasets can share a mean while having wildly different consistency.
- A frequency distribution table groups raw data into class intervals with counts, turning an unreadable list of hundreds of numbers into a shape you can immediately interpret — and is the numeric basis for bar graphs and histograms.
- When mean and median are close, the data is well-behaved; when they diverge sharply, that gap is a signal — check for an outlier before trusting either number blindly.
Practice Exercises
Now it is time to practice! Complete these challenges to solidify your understanding:
- Exercise 1: Write a short program that demonstrates the core concept from this chapter. Test it with at least 3 different inputs.
- Exercise 2: Find a real-world example where statistics is used in an Indian company (like TCS, Infosys, Flipkart, or ISRO). Write a paragraph explaining the connection.
- Exercise 3: Create a mind-map connecting statistics to at least 3 other topics you have studied.