temp_stats.exs in Elixir
A week of daily highs reduced to low, high and mean, with a scaled bar per day.
# One week of daily highs: spread, mean, and a scaled bar chart.
week = [
{"Mon", 61}, {"Tue", 68}, {"Wed", 74}, {"Thu", 79},
{"Fri", 72}, {"Sat", 65}, {"Sun", 58}
]
temps = Enum.map(week, fn {_day, t} -> t end)
lo = Enum.min(temps)
hi = Enum.max(temps)
mean = Enum.sum(temps) / length(temps)
span = max(hi - lo, 1)
# Bars scale to the week's spread; the +1 keeps the coolest day visible.
bar = fn t -> String.duplicate("#", 1 + div(20 * (t - lo), span)) end
diff = fn t ->
shown = Float.round(abs(t - mean), 1)
if t >= mean, do: "+#{shown}", else: "-#{shown}"
end
IO.puts("day high range diff")
IO.puts(String.duplicate("-", 40))
for {day, t} <- week do
IO.puts(
String.pad_trailing(day, 5) <>
String.pad_leading(Integer.to_string(t), 4) <> " " <>
String.pad_trailing(bar.(t), 21) <>
String.pad_leading(diff.(t), 5)
)
end
IO.puts(String.duplicate("-", 40))
IO.puts("low #{lo}, high #{hi}, mean #{Float.round(mean, 1)}")
IO.puts("days above the mean: #{Enum.count(temps, fn t -> t > mean end)}")
How it works
Enum.mapstrips the temps out;Enum.min,Enum.maxand a division set the spread.barscales each day against the spread anddiffsigns the distance from the mean.- The
forloop pads each row into columns; the footer counts the days above the mean.
Keywords and builtins used here
EnumFloatIOIntegerStringdoendfnforif
The run, in numbers
- Lines
- 35
- Characters to type
- 1022
- Tokens
- 344
- Three-star pace
- 70 tpm
At the three-star pace of 70 tokens a minute, this run takes about 295 seconds.
Step 3 of 3 in Encore, step 27 of 27 in Language basics.