Module 4 · Location, Ranking, and Exploratory Summaries Lesson 34 of 120
Median and Mode
A typical settlement delay by order and frequency.
Transcript
21 sentences · select one to jump thereCheck your understanding
Does an unchanged median prove no customer had a severe delay?
Code lab
Run it yourself
The lesson source in 7 languages. Edit it, run TypeScript and Python right here, and compare with the expected output.
/**
* Fintech Math Bootcamp · Lesson 034 of 120
* Median and Mode
* Module 04: Location, Ranking, and Exploratory Summaries
*
* Scenario: A typical settlement delay by order and frequency
* Rule: median = middle order statistic; mode = most frequent value
*
* Try it: Does an unchanged median prove no customer had a severe delay?
*
* Lesson article: https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/location-ranking-and-exploratory-summaries/median-and-mode/
* Free course: https://courses.thefintechbuilder.com
* Synthetic teaching example, not financial advice or a production library.
*/
export function lesson034() {
const x = [1, 2, 2, 4, 9].sort((a,b) => a-b);
const mid = Math.floor(x.length / 2);
const median = x.length % 2 ? x[mid] : (x[mid-1] + x[mid]) / 2;
const counts = new Map<number, number>();
for (const v of x) counts.set(v, (counts.get(v) ?? 0) + 1);
const maxCount = Math.max(...counts.values());
const modes = [...counts].filter(([,n]) => n===maxCount).map(([v]) => v);
const result = {median, modes};
return result;
}
export const checkedResult = {"median":2,"modes":[2]};
// Run this file directly: npx tsx lessons/04-location-ranking-and-exploratory-summaries/034-median-and-mode.ts
if (process.argv[1] && import.meta.url.endsWith(process.argv[1].replace(/\\/g, "/").split("/").pop()!)) {
console.log(JSON.stringify(lesson034(), null, 2));
}
Your output
Press Run to execute the code in your browser.
Expected output
{
"median": 2,
"modes": [
2
]
}# Fintech Math Bootcamp · Lesson 034 of 120
# Median and Mode
# Module 04: Location, Ranking, and Exploratory Summaries
#
# Scenario: A typical settlement delay by order and frequency
# Rule: median = middle order statistic; mode = most frequent value
#
# Try it: Does an unchanged median prove no customer had a severe delay?
#
# Lesson article: https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/location-ranking-and-exploratory-summaries/median-and-mode/
# Free course: https://courses.thefintechbuilder.com
# Synthetic teaching example, not financial advice or a production library.
import json
def lesson034() -> dict:
x = sorted([1, 2, 2, 4, 9])
mid = len(x) // 2
median = x[mid] if len(x) % 2 else (x[mid - 1] + x[mid]) / 2
counts: dict[float, int] = {}
for v in x:
counts[v] = counts.get(v, 0) + 1
max_count = max(counts.values())
modes = [v for v, n in counts.items() if n == max_count]
return {"median": median, "modes": modes}
if __name__ == "__main__":
print(json.dumps(lesson034(), indent=2))
Your output
Press Run to execute the code in your browser.
Expected output
{
"median": 2,
"modes": [
2
]
}/**
* Fintech Math Bootcamp · Lesson 034 of 120
* Median and Mode
* Module 04: Location, Ranking, and Exploratory Summaries
*
* Scenario: A typical settlement delay by order and frequency
* Rule: median = middle order statistic; mode = most frequent value
*
* Try it: Does an unchanged median prove no customer had a severe delay?
*
* Lesson article: https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/location-ranking-and-exploratory-summaries/median-and-mode/
* Free course: https://courses.thefintechbuilder.com
* Synthetic teaching example, not financial advice or a production library.
*/
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class Main {
static Map<String, Object> lesson034() {
double[] x = {1, 2, 2, 4, 9};
Arrays.sort(x);
int mid = x.length / 2;
double median = x.length % 2 == 1 ? x[mid] : (x[mid - 1] + x[mid]) / 2;
Map<Double, Integer> counts = new LinkedHashMap<Double, Integer>();
for (double v : x) {
Integer seen = counts.get(v);
counts.put(v, seen == null ? 1 : seen + 1);
}
int maxCount = Collections.max(counts.values());
List<Double> modes = new ArrayList<Double>();
for (Map.Entry<Double, Integer> entry : counts.entrySet()) {
if (entry.getValue() == maxCount) modes.add(entry.getKey());
}
Map<String, Object> result = new LinkedHashMap<String, Object>();
result.put("median", median);
result.put("modes", modes);
return result;
}
public static void main(String[] args) {
System.out.println(toJson(lesson034(), ""));
}
// --- Minimal JSON printer: maps keep insertion order, 2-space indent. ---
static String toJson(Object value, String indent) {
if (value == null) return "null";
if (value instanceof String) return "\"" + value + "\"";
if (value instanceof Double) return formatNumber((Double) value);
if (value instanceof Number) return value.toString();
if (value instanceof double[]) {
List<Object> items = new ArrayList<Object>();
for (double v : (double[]) value) items.add(v);
return toJson(items, indent);
}
String inner = indent + " ";
StringBuilder sb = new StringBuilder();
if (value instanceof Map) {
Map<?, ?> map = (Map<?, ?>) value;
if (map.isEmpty()) return "{}";
sb.append("{\n");
int i = 0;
for (Map.Entry<?, ?> entry : map.entrySet()) {
sb.append(inner).append('"').append(entry.getKey()).append("\": ")
.append(toJson(entry.getValue(), inner))
.append(++i < map.size() ? ",\n" : "\n");
}
return sb.append(indent).append('}').toString();
}
List<?> list = (List<?>) value;
if (list.isEmpty()) return "[]";
sb.append("[\n");
for (int i = 0; i < list.size(); i++) {
sb.append(inner).append(toJson(list.get(i), inner))
.append(i + 1 < list.size() ? ",\n" : "\n");
}
return sb.append(indent).append(']').toString();
}
static String formatNumber(double v) {
if (Double.isNaN(v) || Double.isInfinite(v)) return "null";
if (v == Math.rint(v) && Math.abs(v) < 1e15) return Long.toString((long) v);
return Double.toString(v);
}
}
No browser runner for Java yet
Read the code here, then run it in your own toolchain or a ready-made cloud workspace.
Expected output
{
"median": 2,
"modes": [
2
]
}// Fintech Math Bootcamp · Lesson 034 of 120
// Median and Mode
// Module 04: Location, Ranking, and Exploratory Summaries
//
// Scenario: A typical settlement delay by order and frequency
// Rule: median = middle order statistic; mode = most frequent value
//
// Try it: Does an unchanged median prove no customer had a severe delay?
//
// Lesson article: https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/location-ranking-and-exploratory-summaries/median-and-mode/
// Free course: https://courses.thefintechbuilder.com
// Synthetic teaching example, not financial advice or a production library.
package main
import (
"encoding/json"
"fmt"
"sort"
)
// Location holds the middle order statistic and every most-frequent value.
type Location struct {
Median float64 `json:"median"`
Modes []float64 `json:"modes"`
}
func lesson034() Location {
x := []float64{1, 2, 2, 4, 9}
sort.Float64s(x)
mid := len(x) / 2
var median float64
if len(x)%2 == 1 {
median = x[mid]
} else {
median = (x[mid-1] + x[mid]) / 2
}
// Count each value, remembering the order values first appear.
counts := map[float64]int{}
var order []float64
for _, v := range x {
if counts[v] == 0 {
order = append(order, v)
}
counts[v]++
}
maxCount := 0
for _, n := range counts {
maxCount = max(maxCount, n)
}
modes := []float64{}
for _, v := range order {
if counts[v] == maxCount {
modes = append(modes, v)
}
}
return Location{Median: median, Modes: modes}
}
func main() {
out, _ := json.MarshalIndent(lesson034(), "", " ")
fmt.Println(string(out))
}
No browser runner for Go yet
Read the code here, then run it in your own toolchain or a ready-made cloud workspace.
Expected output
{
"median": 2,
"modes": [
2
]
}/**
* Fintech Math Bootcamp · Lesson 034 of 120
* Median and Mode
* Module 04: Location, Ranking, and Exploratory Summaries
*
* Scenario: A typical settlement delay by order and frequency
* Rule: median = middle order statistic; mode = most frequent value
*
* Try it: Does an unchanged median prove no customer had a severe delay?
*
* Lesson article: https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/location-ranking-and-exploratory-summaries/median-and-mode/
* Free course: https://courses.thefintechbuilder.com
* Synthetic teaching example, not financial advice or a production library.
*/
#include <algorithm>
#include <charconv>
#include <cmath>
#include <iostream>
#include <string>
#include <utility>
#include <vector>
// --- Minimal JSON value and printer: objects keep insertion order, 2-space indent. ---
struct Json {
enum class Kind { Null, Number, Text, Array, Object };
Kind kind = Kind::Null;
double number = 0;
std::string text;
std::vector<std::string> keys; // object keys, parallel to items
std::vector<Json> items; // array elements or object values
};
Json num(double v) { Json j; j.kind = Json::Kind::Number; j.number = v; return j; }
Json str(const std::string& s) { Json j; j.kind = Json::Kind::Text; j.text = s; return j; }
Json arr(const std::vector<Json>& values) { Json j; j.kind = Json::Kind::Array; j.items = values; return j; }
Json arr(const std::vector<double>& values) {
std::vector<Json> items;
for (double v : values) items.push_back(num(v));
return arr(items);
}
Json obj(const std::vector<std::pair<std::string, Json>>& fields) {
Json j;
j.kind = Json::Kind::Object;
for (const auto& [key, value] : fields) { j.keys.push_back(key); j.items.push_back(value); }
return j;
}
std::string formatNumber(double v) {
if (!std::isfinite(v)) return "null";
char buf[64];
auto end = std::to_chars(buf, buf + sizeof buf, v).ptr; // shortest round-trip form
return std::string(buf, end);
}
void writeJson(std::ostream& out, const Json& j, const std::string& indent) {
switch (j.kind) {
case Json::Kind::Null: out << "null"; return;
case Json::Kind::Number: out << formatNumber(j.number); return;
case Json::Kind::Text: out << '"' << j.text << '"'; return;
default: break;
}
bool isObject = j.kind == Json::Kind::Object;
if (j.items.empty()) { out << (isObject ? "{}" : "[]"); return; }
std::string inner = indent + " ";
out << (isObject ? "{\n" : "[\n");
for (size_t i = 0; i < j.items.size(); ++i) {
out << inner;
if (isObject) out << '"' << j.keys[i] << "\": ";
writeJson(out, j.items[i], inner);
out << (i + 1 < j.items.size() ? ",\n" : "\n");
}
out << indent << (isObject ? '}' : ']');
}
// --- Lesson ---
Json lesson034() {
std::vector<double> x = {1, 2, 2, 4, 9};
std::sort(x.begin(), x.end());
size_t mid = x.size() / 2;
double median = x.size() % 2 ? x[mid] : (x[mid - 1] + x[mid]) / 2;
// Count each value in first-seen order.
std::vector<std::pair<double, int>> counts;
for (double v : x) {
auto it = std::find_if(counts.begin(), counts.end(), [v](const auto& c) { return c.first == v; });
if (it == counts.end()) counts.push_back({v, 1});
else ++it->second;
}
int maxCount = 0;
for (const auto& c : counts) maxCount = std::max(maxCount, c.second);
std::vector<double> modes;
for (const auto& c : counts) {
if (c.second == maxCount) modes.push_back(c.first);
}
return obj({{"median", num(median)}, {"modes", arr(modes)}});
}
int main() {
writeJson(std::cout, lesson034(), "");
std::cout << '\n';
}
No browser runner for C++ yet
Read the code here, then run it in your own toolchain or a ready-made cloud workspace.
Expected output
{
"median": 2,
"modes": [
2
]
}// Fintech Math Bootcamp · Lesson 034 of 120
// Median and Mode
// Module 04: Location, Ranking, and Exploratory Summaries
//
// Scenario: A typical settlement delay by order and frequency
// Rule: median = middle order statistic; mode = most frequent value
//
// Try it: Does an unchanged median prove no customer had a severe delay?
//
// Lesson article: https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/location-ranking-and-exploratory-summaries/median-and-mode/
// Free course: https://courses.thefintechbuilder.com
// Synthetic teaching example, not financial advice or a production library.
// --- Minimal JSON value and printer: objects keep insertion order, 2-space indent. ---
#[allow(dead_code)]
enum Json {
Null,
Num(f64),
Str(String),
Arr(Vec<Json>),
Obj(Vec<(String, Json)>),
}
#[allow(dead_code)]
fn nums(values: &[f64]) -> Json {
Json::Arr(values.iter().map(|&v| Json::Num(v)).collect())
}
#[allow(dead_code)]
fn obj(fields: Vec<(&str, Json)>) -> Json {
Json::Obj(fields.into_iter().map(|(k, v)| (k.to_string(), v)).collect())
}
fn format_number(v: f64) -> String {
if !v.is_finite() {
return "null".to_string();
}
if v.fract() == 0.0 && v.abs() < 1e15 {
return format!("{}", v as i64);
}
format!("{:?}", v) // shortest round-trip form
}
impl Json {
fn render(&self, indent: &str) -> String {
let inner = format!("{} ", indent);
match self {
Json::Null => "null".to_string(),
Json::Num(v) => format_number(*v),
Json::Str(s) => format!("\"{}\"", s),
Json::Arr(items) if items.is_empty() => "[]".to_string(),
Json::Obj(fields) if fields.is_empty() => "{}".to_string(),
Json::Arr(items) => {
let lines: Vec<String> = items.iter().map(|v| format!("{}{}", inner, v.render(&inner))).collect();
format!("[\n{}\n{}]", lines.join(",\n"), indent)
}
Json::Obj(fields) => {
let lines: Vec<String> = fields
.iter()
.map(|(k, v)| format!("{}\"{}\": {}", inner, k, v.render(&inner)))
.collect();
format!("{{\n{}\n{}}}", lines.join(",\n"), indent)
}
}
}
}
// --- Lesson ---
fn lesson034() -> Json {
let mut x: Vec<f64> = vec![1.0, 2.0, 2.0, 4.0, 9.0];
x.sort_by(|a, b| a.partial_cmp(b).unwrap());
let mid = x.len() / 2;
let median = if x.len() % 2 == 1 { x[mid] } else { (x[mid - 1] + x[mid]) / 2.0 };
// Count each value in first-seen order.
let mut counts: Vec<(f64, usize)> = Vec::new();
for &v in &x {
match counts.iter_mut().find(|(value, _)| *value == v) {
Some((_, n)) => *n += 1,
None => counts.push((v, 1)),
}
}
let max_count = counts.iter().map(|&(_, n)| n).max().unwrap_or(0);
let modes: Vec<f64> = counts.iter().filter(|&&(_, n)| n == max_count).map(|&(v, _)| v).collect();
obj(vec![("median", Json::Num(median)), ("modes", nums(&modes))])
}
fn main() {
println!("{}", lesson034().render(""));
}
No browser runner for Rust yet
Read the code here, then run it in your own toolchain or a ready-made cloud workspace.
Expected output
{
"median": 2,
"modes": [
2
]
}/**
* Fintech Math Bootcamp · Lesson 034 of 120
* Median and Mode
* Module 04: Location, Ranking, and Exploratory Summaries
*
* Scenario: A typical settlement delay by order and frequency
* Rule: median = middle order statistic; mode = most frequent value
*
* Try it: Does an unchanged median prove no customer had a severe delay?
*
* Lesson article: https://thefintechbuilder.com/financial-mathematics-statistics-and-data-foundations/location-ranking-and-exploratory-summaries/median-and-mode/
* Free course: https://courses.thefintechbuilder.com
* Synthetic teaching example, not financial advice or a production library.
*/
using System;
using System.Linq;
using System.Text.Json;
var options = new JsonSerializerOptions { WriteIndented = true };
Console.WriteLine(JsonSerializer.Serialize(Lesson034(), options));
static object Lesson034()
{
double[] x = new double[] { 1, 2, 2, 4, 9 }.OrderBy(v => v).ToArray();
int mid = x.Length / 2;
double median = x.Length % 2 == 1 ? x[mid] : (x[mid - 1] + x[mid]) / 2;
var counts = x.GroupBy(v => v).Select(g => new { value = g.Key, count = g.Count() }).ToList();
int maxCount = counts.Max(c => c.count);
double[] modes = counts.Where(c => c.count == maxCount).Select(c => c.value).ToArray();
return new { median, modes };
}
No browser runner for C# yet
Read the code here, then run it in your own toolchain or a ready-made cloud workspace.
Expected output
{
"median": 2,
"modes": [
2
]
}Prefer your own machine? Every file is in the course repository · open it in Codespaces.
Lesson notes
The rule
median = middle order statistic; mode = most frequent value