Module:ProbabilityFormat
Appearance
Purpose
This module provides functions to convert fractional probabilities (e.g. `0.01`) into human-friendly text strings such as:
- `"no chance"`
- `"100% chance"`
- `"about 1 in 100"`
- `"almost zero chance (less than 1 in 1,000,000)"`
It is designed for use in templates where probabilities need to be expressed in plain language.
Usage
Basic syntax:
{{#invoke:ProbabilityFormat|convert|probability|cutoff}}
probability
(required) — a number between `0` and `1`.cutoff
(optional) — probabilities smaller than this are treated as “almost zero chance.” Defaults to `1e-6` (1 in 1,000,000).
Parameters
probability
- The fractional probability, either as a number or string (e.g. `0.05`).
cutoff
- A fractional cutoff for “almost zero” reporting. For example, passing `1e-4` will show “less than 1 in 10,000.”
Examples
Input | Output |
---|---|
{{#invoke:ProbabilityFormat|convert|0}} |
no chance |
{{#invoke:ProbabilityFormat|convert|1}} |
100% chance |
{{#invoke:ProbabilityFormat|convert|0.95}} |
almost certain (more than 9 in 10) |
{{#invoke:ProbabilityFormat|convert|0.7}} |
about 7 in 10 |
{{#invoke:ProbabilityFormat|convert|0.01}} |
about 1 in 100 |
{{#invoke:ProbabilityFormat|convert|1e-8}} |
almost zero chance (less than 1 in 1,000,000) |
{{#invoke:ProbabilityFormat|convert|1e-5|1e-4}} |
almost zero chance (less than 1 in 10,000) |
See also
local p = {}
-- Format an integer with commas as thousands separators
local function format_with_commas(n)
local s = tostring(n)
local sign, int = s:match("^([%-]?)(%d+)$")
int = int:reverse():gsub("(%d%d%d)", "%1,")
int = int:reverse():gsub("^,", "")
return sign .. int
end
-- Converts a fractional probability to a human-friendly "1 in X" string
-- @param frame.args[1] Probability in [0,1] (string or number)
-- @param frame.args[2] (optional) Cutoff for "almost zero chance"
-- @return A string like "1 in 100", "no chance", or "100% chance"
function p.convert(frame)
--[[ Implementation details:
- Handles 0 or negative as "no chance"
- Handles >=1 as "100% chance"
- Rounds reciprocal to one significant digit ]]
local prob_str = frame.args[1]
-- Check for valid input
if prob_str == nil or prob_str == '' then
return "Error: No probability provided"
end
local prob = tonumber(prob_str)
if not prob then
return "Error: Invalid probability"
end
local cutoff = tonumber(frame.args[2]) or 1e-6
-- Handle special cases
if prob <= 0 then
return "no chance"
elseif prob < cutoff then
return "almost zero chance (less than 1 in "
.. format_with_commas(math.floor(1 / cutoff)) .. ")"
elseif prob >= 1 then
return "100% chance"
elseif prob >= 0.95 then
return "almost certain (more than 9 in 10)"
elseif prob >= 0.55 then
-- Probabilities close to 1 (more than 1 in 2): Express as "6/7/8/9 in 10"
local n = math.floor(prob*10 + 0.5)
return "about " .. n .. " in 10"
else
-- Calculate and round to one significant digit
local recip = 1 / prob
local exponent = math.floor(math.log10(recip))
local mantissa = recip / (10 ^ exponent)
local rounded_mant = math.floor(mantissa + 0.5)
local rounded = rounded_mant * (10 ^ exponent)
return "about 1 in " .. format_with_commas(math.floor(rounded))
end
end
return p