Skip to Content
Course content

227: The statistics Module Basics

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Imagine you're monitoring a microservice and you've collected a list of response times (latencies) in milliseconds. You want to get a feel for the performance—maybe find the average or the "middle" value—to see if a few outliers are skewing your perception of the system's health. Most of us start by reaching for the basics we remember from math class.

The Manual Calculation Trap

If you just need a simple average, the naive approach is pretty straightforward. You probably already know the pattern: sum the list and divide by the length. It looks like this:

latencies = [120, 150, 130, 110, 1000, 140, 130]
average = sum(latencies) / len(latencies)
# Result: 252.85...

For a mean, this is fine. But here is where I see developers start to struggle: the moment you need the median or the mode. To calculate the median manually, you have to sort the list, find the middle index, and then write a conditional block to handle whether the list length is even or odd. If you want the mode (the most frequent value), you're suddenly building a dictionary to count occurrences, sorting that dictionary by value, and extracting the key. It's a lot of boilerplate code for a very common task, and every line of manual logic is just another place for a bug to hide.

Letting the Standard Library Handle the Edge Cases

Python's statistics module exists specifically so you don't have to write that boilerplate. I always recommend it because it's more readable and, more importantly, it handles the mathematical edge cases that we usually forget. Instead of rolling your own logic, you just import the tools you need.

import statistics

latencies = [120, 150, 130, 110, 1000, 140, 130]

mean_val = statistics.mean(latencies)
median_val = statistics.median(latencies)
mode_val = statistics.mode(latencies)

print(f"Mean: {mean_val}, Median: {median_val}, Mode: {mode_val}")
# Result: Mean: 252.85, Median: 130, Mode: 130

Notice how the median and mode are 130, while the mean is over 250? That's the "aha!" moment. That single 1000ms spike (the outlier) completely dragged the mean upward, giving you a false impression that the service is slow. The statistics module makes it trivial to compare these values, which is the only way to actually understand your data.

The Cost of Empty Data

One thing to be careful about: both the manual way and the statistics module will crash if you pass them an empty list. The manual way gives you a ZeroDivisionError, but the statistics module raises a statistics.StatisticsError. I prefer the latter because it's more explicit about why the failure happened—it wasn't just a math error; it was a data error.

When you're implementing this in a real production script, I'd suggest wrapping your calls in a try-except block. It's a small habit, but it saves you from a midnight page when a monitoring probe returns an empty set of results.




📋 Practical Task

Analyzing Website Load-Time Variance

You have been given a list of page load times (in seconds) for a new landing page. Some of these requests were unusually slow due to a cold cache, and others were very fast.

Your Task:

  • Create a list named load_times with the following values: [2.5, 3.1, 2.2, 2.5, 15.0, 2.8, 2.5, 3.0, 2.1].
  • Use the statistics module to calculate the mean, median, and mode of these load times.
  • Print the results.
  • Add a second, empty list called no_data = [] and wrap a call to statistics.mean(no_data) in a try/except block that specifically catches statistics.StatisticsError and prints "No data available to analyze" instead of letting the program crash.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.