# Program 3: Variance, standard deviation and outliers
# Minutes taken by 20 students to finish a quiz. One student left the
# quiz open and came back much later - an outlier.

import numpy as np
import matplotlib.pyplot as plt

minutes = np.array([12, 14, 11, 15, 13, 12, 16, 14, 13, 12,
                    15, 11, 14, 13, 58, 12, 15, 13, 14, 12])

mean = np.mean(minutes)
variance = np.var(minutes)
sd = np.std(minutes)
print("Mean               :", round(mean, 2), "minutes")
print("Variance           :", round(variance, 2))
print("Standard deviation :", round(sd, 2), "minutes")
print()

# An outlier lies an abnormal distance from the other values. A common
# rule: more than 2 standard deviations away from the mean.
low = mean - 2 * sd
high = mean + 2 * sd
print("Normal range       :", round(low, 2), "to", round(high, 2), "minutes")
outliers = minutes[(minutes < low) | (minutes > high)]
print("Outliers           :", outliers)
print()

# Without the outlier, the mean and standard deviation tell the truth.
clean = minutes[(minutes >= low) & (minutes <= high)]
print("Without the outlier:")
print("Mean               :", round(np.mean(clean), 2), "minutes")
print("Standard deviation :", round(np.std(clean), 2), "minutes")

# The distribution of the times, as a histogram.
plt.hist(minutes, bins=12, color="#4e79a7", edgecolor="white")
plt.axvline(mean, color="#e15759", linestyle="--", label="Mean with the outlier")
plt.title("Minutes taken to finish the quiz")
plt.xlabel("Minutes")
plt.ylabel("Number of students")
plt.legend()
plt.show()
