Coding is communication1. Stating the intent of a system to your colleagues is as important as the implementation itself, if not more. Sometimes the signature of a function doesn’t reflect the intention, or maybe the implementation hides a nasty side-effect.
As [[Richard Feynman]] famously said, [[What I cannot create, I do not understand]]. And teaching is both arguably the most effective way of comprehension and really fun! Swapping the hardworking-progammer-boots to professor-sneakers imposes a different lens on our own code — one that requires clarity and empathy2. This, in part, is a way of [[Literate programming]].
Words don’t often feel enough. Ideally I’d pull my teammate to the whiteboard and get them through my thought process. Source code files are, however, blissfully constrained by their text nature, at odds with our intention at hand. Under these circumstances, I find diagramming in plain text immensely valuable as an proxy for understanding.
There are very decent programs focused on unicode drawings. Online, [[MonoSketch]] and [[wiretext.app]]; and for desktop, [[Monodraw]].
Some examples
Here’s a diagram showing how to obtain the input for a specific image given that the function is monotonically decreasing within .
╭────────────────╮
│ d(t) ~ Ae^(-Bt)│
│ ╰────────────────╯
1 ──╲╲╲─────────────────────────────────────────────────────────────────
│ ╲╲╲╲╲╲
│ ╲╲╲╲╲╲
│ ╲╲╲╲╲╲
│ ╲╲╲╲╲╲
│ ╲╲╲╲╲╲
│ ╲╲╲╲╲╲
│ ╲╲╲╲╲╲
target ─────────────────────────────────────────────────→╲╲╲
/ enriched score │ │ ╲╲╲╲╲╲
│ │ ╲╲╲╲╲╲
│ ↓ ╲╲╲╲
──│──●──────────────────────────────────────────────●──────────●───────→
t_m t_0 t_MRelatedly, sampling values alongside that function:
1.0 │╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶
│••••••
│ •••••••
│ •••••
│ •••••
│ •••••
│ ••••
│ •••
│ •
│ ••
│ ••
└──────────────────────────────••••••••••── time
* * * * * * * * * * * drawn samplesA fold over an inline selection which might catch you off-guard:
attribute_score_records: list[AttributeScoreRecord] = [
score_attribute(
attribute=attribute,
at_timestamp=at_timestamp,
previous_sighting=attribute_sightings.get(attribute.value),
assessments=assessments_by_value.get(attribute.value, []),
parameters=attribute_parameters,
)
# only take those attributes that make sense to evaluate
# IoC1 at IoC2
# ─────── · ──── ⋮ ──────── · ────────
# 11:15 11:20 13:20
# cuts off IoC2
for attribute in filter(lambda a: a.sighting <= at_timestamp and a.to_ids, all_attributes)
]This one explains a rolling window
# all periods
# equals to
# [all periods - to evaluate] : first(to evaluate) : tail(to evaluate)
# which means that the previous period to the first to evaluate is the last element
# from all periods
# ╭──────────────────────────────────────────────╮
# │ │
# │ ┌───────────┐ │
# │ │░░░░░░░░░░░│ │
# │ │░░░░░░░░░░░│ │
# │ │░░░░░░░┌───┴──────────────┐ │
# │ │░░░░░░░│▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒│ │
# ├─┼─○─○─○────●──────┼─●─────┼──●──────●──────●─┼─┼───●────▶
# │ t5 │t6░░░░░│▒t7▒▒▒▒▒t8▒▒▒▒▒t9▒│ │ now
# │ │░░░░░░░│▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒│ │
# │ │░░░░░░░└───┬──────────────┘ │
# │ │░░░░░░░░░░░│ evaluation │
# │ └───────────┘ window │
# │ previous │
# │ period │
# ╰──────────────────────────────────────────────╯
# all periods known to service