Python data#
Make a small dataset with only the Python standard library, summarize it, and then draw a chart that follows a number you can move. Run the blocks from the top.
Generate a dataset#
A week of made-up request counts for three services, from a fixed seed so everyone sees the same numbers.
import random
rng = random.Random(7)
services = ["api", "web", "worker"]
rows = []
for day in range(1, 8):
for name in services:
base = {"api": 120, "web": 200, "worker": 60}[name]
rows.append((day, name, base + rng.randint(-25, 25)))
print(len(rows), "rows")
for row in rows[:6]:
print(row)21 rows
(1, 'api', 115)
(1, 'web', 184)
(1, 'worker', 60)
(2, 'api', 136)
(2, 'web', 178)
(2, 'worker', 39)Summarize it#
import statistics
for name in services:
counts = [n for (_, s, n) in rows if s == name]
print(f"{name:7} min {min(counts):4} max {max(counts):4} "
f"mean {statistics.mean(counts):7.2f} stdev {statistics.stdev(counts):6.2f}")
busiest = max(rows, key=lambda r: r[2])
print("busiest:", busiest)api min 108 max 136 mean 121.71 stdev 11.06
web min 177 max 201 mean 182.71 stdev 8.40
worker min 39 max 70 mean 53.29 stdev 13.66
busiest: (6, 'web', 201)from collections import defaultdict
by_day = defaultdict(int)
for day, _, n in rows:
by_day[day] += n
for day in sorted(by_day):
bar = "#" * (by_day[day] // 20)
print(f"day {day}: {by_day[day]:4} {bar}")day 1: 359 #################
day 2: 353 #################
day 3: 368 ##################
day 4: 377 ##################
day 5: 325 ################
day 6: 362 ##################
day 7: 360 ##################A live chart#
The number amplitude = 1 scales a daily temperature swing. Drag it or use the arrow keys when it has focus. The block below prints a table, and the chart under it draws that table again after every Run.
import math
rows_t = [
[hour, round(18 + 5 * float(amplitude) * math.sin((hour - 9) / 24 * 2 * math.pi), 2)]
for hour in range(0, 25, 2)
]
display({"application/vnd.wmn.table+json": {"columns": ["hour", "temperature"], "rows": rows_t}}, raw=True)
print(len(rows_t), "readings, amplitude", amplitude)| hour | temperature |
|---|---|
| 0 | 14.46 |
| 2 | 13.17 |
| 4 | 13.17 |
| 6 | 14.46 |
| 8 | 16.71 |
| 10 | 19.29 |
| 12 | 21.54 |
| 14 | 22.83 |
| 16 | 22.83 |
| 18 | 21.54 |
| 20 | 19.29 |
| 22 | 16.71 |
| 24 | 14.46 |
13 readings, amplitude 1Lines through a table's numeric columns, with a cursor that reads each point stdlib/charts@1.0.1
Show block text
source: temperature
x: hour
y: temperature
title: Temperature by hourThe chart is drawn from the table saved with the page when you open it. After a Run it is drawn from what the machine printed, and Reset under the chart goes back to the saved table.
Counts as a histogram#
rng2 = random.Random(3)
values = [round(rng2.lognormvariate(3.2, 0.5), 1) for _ in range(200)]
display({"application/vnd.wmn.table+json": {"columns": ["ms"], "rows": [[v] for v in values]}}, raw=True)
print("200 samples, median", sorted(values)[100])| ms |
|---|
| 15 |
| 18.5 |
| 27.5 |
| 18.7 |
| 42.6 |
| 28.2 |
| 58.9 |
| 26.5 |
| 28.7 |
| 42.2 |
| 20.6 |
| 44.5 |
| 15.6 |
| 11.7 |
| 16.5 |
| 49.8 |
| 28.7 |
| 24.8 |
| 18 |
| 52.2 |
| 29.2 |
| 54.9 |
| 31 |
| 47.8 |
| 20.1 |
| 22.4 |
| 11.4 |
| 27.2 |
| 32.5 |
| 20.6 |
| 26.8 |
| 15.8 |
| 27.4 |
| 42.4 |
| 22.9 |
| 33.3 |
| 28 |
| 52.8 |
| 19.9 |
| 17.8 |
| 57.7 |
| 25.6 |
| 20.6 |
| 27.7 |
| 30.1 |
| 31.1 |
| 48.3 |
| 16.6 |
| 27.6 |
| 20.7 |
| 18.6 |
| 18.6 |
| 30.7 |
| 19.9 |
| 34.5 |
| 15.3 |
| 29.6 |
| 19.5 |
| 40.8 |
| 35.4 |
| 16.4 |
| 44.8 |
| 18.8 |
| 25.3 |
| 16.8 |
| 51.2 |
| 36.6 |
| 15.7 |
| 34.7 |
| 19.6 |
| 21.8 |
| 7.9 |
| 39.3 |
| 89.1 |
| 32.8 |
| 18.6 |
| 19.1 |
| 27.3 |
| 55.2 |
| 16.4 |
| 32.9 |
| 7.3 |
| 28.4 |
| 22.4 |
| 20.9 |
| 28.9 |
| 54.7 |
| 14.4 |
| 16.1 |
| 21.6 |
| 12 |
| 19.5 |
| 17.1 |
| 27.6 |
| 16.5 |
| 11.9 |
| 33.1 |
| 15.8 |
| 18.6 |
| 36.3 |
| 48.7 |
| 22.3 |
| 24.3 |
| 19.6 |
| 23.5 |
| 27.1 |
| 12.9 |
| 14.5 |
| 44.6 |
| 16.8 |
| 84.4 |
| 52.2 |
| 38.8 |
| 10.7 |
| 36.5 |
| 60.9 |
| 61.7 |
| 39.2 |
| 30.2 |
| 14.1 |
| 33.8 |
| 18.7 |
| 14 |
| 35.1 |
| 20.3 |
| 19.7 |
| 12 |
| 49 |
| 31.6 |
| 48 |
| 33.4 |
| 23.6 |
| 36.6 |
| 51.4 |
| 20.6 |
| 17 |
| 13.2 |
| 19.9 |
| 13.5 |
| 14.8 |
| 27.1 |
| 23.8 |
| 15.8 |
| 12.5 |
| 23.5 |
| 20.8 |
| 45.7 |
| 23.2 |
| 40.9 |
| 23.7 |
| 11 |
| 36.6 |
| 17.1 |
| 9.9 |
| 18.6 |
| 30.4 |
| 18.6 |
| 30.3 |
| 13 |
| 22.1 |
| 13.5 |
| 46.6 |
| 25.6 |
| 13.8 |
| 44.9 |
| 64.3 |
| 14.3 |
| 48.5 |
| 10.8 |
| 25.4 |
| 24.3 |
| 43.9 |
| 26.3 |
| 34.4 |
| 28.6 |
| 14.6 |
| 29.6 |
| 31 |
| 20.2 |
| 39.6 |
| 33.8 |
| 17.7 |
| 24.7 |
| 35.1 |
| 19.3 |
| 28.7 |
| 10.8 |
| 15.5 |
| 59 |
| 17.6 |
| 18.6 |
| 72.1 |
| 26.9 |
| 22 |
| 25.9 |
| 17.4 |
| 45.8 |
| 27.3 |
| 30.8 |
| 44.6 |
200 samples, median 25.4How the values of one column are spread: bins, cumulative share, median and the P95 and P99 tails stdlib/charts@1.0.1
Show block text
source: latencies
column: ms
bins: 12
title: Response time