The request

From Laura Bennett, Head of Finance
Your goal
Set result to a dictionary with keys 'total' (sum of orders, an int), 'running' (the running total, np.cumsum, as a list of 14 ints), 'mean' and 'median' (of orders, rounded to 2), 'std' and 'var' (np.std and np.var with their default settings, rounded to 2), and 'growth_index' (the month-on-month growth factors of monthly (each month divided by the month before), compounded with np.cumprod, rounded to 3, as a list of 5 floats).
- Store a dict in
resultnot done yet
Your code
Loading the editor…
Reference solution
Mote checks your result
Press Run. Each row that matches the goal becomes a firefly in your lantern.
What Laura gets, and why
The lesson
Totals and running totals
sum gives one number; cumsum gives the total so far at every position:
orders.sum() # 398
np.cumsum(orders) # [23, 47, 64, 86, ..., 289, 340, 398]
The running total is what a “month to date” line on a dashboard shows. Its last value always equals the plain sum, which is a quick check. Reading it is easy too: after the first week (position 7) the store was at 152 orders; Black Friday weekend alone then added 165.
Mean, median and spread
np.mean(orders) # 28.43
np.median(orders) # 22.5
np.std(orders) # 14.23
np.var(orders) # 202.39
The mean adds everything and divides by 14. The median is the middle value once sorted (with an even count, the average of the two middle ones). Here they disagree a lot: three huge Black Friday days drag the mean up to 28.43, while the median, 22.5, still describes a normal day. When a few extreme values sit in the data, report the median as the “typical” value.
The variance is the average squared distance from the mean, and the standard deviation is its
square root, in the same units as the data: daily orders typically sit about 14 away from the mean.
NumPy divides by n by default. pandas divides by n - 1 (the sample version), so
pd.Series(orders).std() gives 14.76. Pass ddof=1 to NumPy if you need to match.
Compounding growth with cumprod
cumprod multiplies as it goes. That makes it the tool for compounding growth rates:
monthly = np.array([296, 235, 326, 318, 352, 352])
growth = monthly[1:] / monthly[:-1] # [0.794, 1.387, 0.975, 1.107, 1.0]
np.cumprod(growth) # [0.794, 1.101, 1.074, 1.189, 1.189]
February was down 21% on January, March up 39% on February. Compounded, March sits 10% above January and June 19% above it, exactly 352 / 296. Adding the percentage changes instead of multiplying them would give the wrong answer.
Common mistakes
- Comparing
np.stdwith a pandas.std()and thinking one is broken. They use different divisors. - Adding growth rates instead of multiplying factors.
- Reporting the mean as “a typical day” when a few big days skew it.
- Dividing the wrong way round (
monthly[:-1] / monthly[1:]), which turns growth into decline.
Lantern lit!
Practised: numpycumsumcumprodmean medianstd var
- Solved
- No hints
- First run
