statistics.ry
module statistics
purpose: Mean, median and standard deviation of the numbers given on the command line.
import std.console
import std.environment
public function mean(values: List of Float) returns maybe Float
purpose: The arithmetic mean, or nothing for an empty list.
example: mean([2.0, 4.0]) is 3.0
example: mean([]) is nothing
if values.is_empty() then return nothing end
let total be for each value in values sum value
return total / values.length().to_float()
end
public function median(values: List of Float) returns maybe Float
purpose: The middle value of the sorted list, or the mean of the two middle values.
example: median([3.0, 1.0, 2.0]) is 2.0
example: median([4.0, 1.0, 3.0, 2.0]) is 2.5
example: median([]) is nothing
let sorted_values be values.sorted()
let middle be sorted_values.length().quotient(2)
if sorted_values.length() remainder 2 is 1 then return sorted_values.at(middle) end
let lower be sorted_values.at(middle - 1) otherwise return nothing
let upper be sorted_values.at(middle) otherwise return nothing
return (lower + upper) / 2.0
end
public function standard_deviation(values: List of Float) returns maybe Float
purpose: The population standard deviation, or nothing for an empty list.
tags: statistics, float
example: standard_deviation([2.0, 4.0, 4.0, 4.0, 5.0, 5.0, 7.0, 9.0]) is 2.0
let average be mean(values) otherwise return nothing
let squared_total be for each value in values sum (value - average) power 2
return (squared_total / values.length().to_float()).square_root()
end
function describe(label: Text, value: maybe Float) returns Text
match value
when some(number) then return "{label}: {number.rounded(3)}"
when nothing then return "{label}: no data"
end
end
public function main() needs console, environment
purpose: Print the statistics of the numbers on the command line, skipping other words.
let mutable values: List of Float be []
for each argument in environment.arguments()
match argument.to_float()
when success(value) then change values to values.append(value)
when failure(error) then console.print("skipping {argument}: {error.to_text()}")
end
end
console.print(describe(label: "mean", value: mean(values)))
console.print(describe(label: "median", value: median(values)))
console.print(describe(label: "standard deviation", value: standard_deviation(values)))
end