# math — Statistics and Random Numbers > `import { avg, stdDev, median, percentile, getRandomNumber, getRandomNumbers } from 'puffy-core/math'` > CJS: `const { math: { avg, stdDev, median, percentile, getRandomNumber, getRandomNumbers } } = require('puffy-core')` > Also available in snake_case: `std_dev`, `get_random_number`, `get_random_numbers` --- ## avg Arithmetic mean of an array. ### Signature ``` avg(arr: Array, fn?: (item) => number) → number|null ``` Parameters: - `arr`: Array of numbers (or objects if using `fn`) - `fn` (optional): Mapper function to extract a numeric value from each item Returns: Mean value, or `null` for empty arrays. ### Examples ```js avg([5,5,5,5,5]) // 5 avg([1,2,3,4]) // 2.5 avg([]) // null // With mapper function for objects avg([{ v:10 }, { v:20 }, { v:30 }], x => x.v) // 20 ``` --- ## stdDev Sample standard deviation of an array. ### Signature ``` stdDev(arr: Array, fn?: (item) => number) → number|null ``` ### Examples ```js stdDev([5,5,5,5,5]) // 0 stdDev([1,2,3,4]) // 1.118033988749895 stdDev([]) // null stdDev([{ v:10 }, { v:20 }], x => x.v) // 7.0710678118654755 ``` --- ## median Middle value of a sorted array. ### Signature ``` median(arr: Array, fn?: (item) => number) → number ``` Returns: Middle element for odd-length arrays, average of two middle elements for even-length. Returns `0` for empty arrays. ### Examples ```js median([5,5,5,5,5]) // 5 median([1,2,3,4]) // 2.5 — average of 2 and 3 median([3,1,2]) // 2 — sorted: [1,2,3], middle is 2 median([]) // 0 ``` --- ## percentile Curried function that calculates the nth percentile using nearest-rank algorithm. ### Signature ``` percentile(nth: number) → (arr: Array, fn?: (item) => number) → number ``` Parameters: - `nth`: Percentile to calculate (integer 0-100) Returns: A function that accepts an array and returns the percentile value. ### Examples ```js const p5 = percentile(5) const p75 = percentile(75) const p95 = percentile(95) const data = [12,45,23,87,13,54,23,12,1,1,23,67,54,34,35,43,27,56] p5(data) // 1 p75(data) // 54 p95(data) // 87 // Reuse on different arrays p95([10,20,30,40,50,60,70,80,90,100]) // 100 // With mapper function p75([{ v:10 }, { v:20 }, { v:30 }, { v:40 }], x => x.v) // 30 // Edge cases percentile(0)(data) // 1 — minimum percentile(100)(data) // 87 — maximum ``` GOTCHA: `percentile` is curried — it returns a function, not a value. You must call it twice: ```js // WRONG — returns a function, not a number percentile(95, myArray) // CORRECT — call twice percentile(95)(myArray) ``` --- ## getRandomNumber Generates a random number. ### Signature ``` getRandomNumber(options?: { start?: number, end?: number }) → number ``` ### Examples ```js // No args — random float between 0 and 1 getRandomNumber() // 0.37165509291630117 // start only — random INTEGER in [0, start) getRandomNumber({ start:100 }) // Random int 0-99 // start and end — random INTEGER in [start, end) getRandomNumber({ start:1000, end:3000 }) // Random int 1000-2999 ``` GOTCHA: When only `start` is provided, it acts as the **upper bound** (exclusive), NOT the lower bound. The range becomes `[0, start)`: ```js getRandomNumber({ start:100 }) // [0, 100) — NOT [100, ...) getRandomNumber({ start:100, end:200 }) // [100, 200) — start is lower bound here ``` GOTCHA: With `start` and/or `end`, the result is always an integer (uses `Math.floor`). Without arguments, the result is a float. --- ## getRandomNumbers Generates multiple unique random integers. ### Signature ``` getRandomNumbers(options: { start: number, end: number, size: number }) → number[] ``` Returns: Array of `size` unique random integers in `[start, end)`. ### Examples ```js getRandomNumbers({ start:1000, end:3000, size:5 }) // e.g., [1434, 2276, 2468, 1881, 1095] // All values unique, all within [1000, 3000) ``` GOTCHA: Throws if `size` exceeds the available range (`end - start`).