Skip to content

Instantly share code, notes, and snippets.

@magJ
Last active June 2, 2026 02:13
Show Gist options
  • Select an option

  • Save magJ/6d893697c182a29d3f4bd3742a865661 to your computer and use it in GitHub Desktop.

Select an option

Save magJ/6d893697c182a29d3f4bd3742a865661 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
"""Calculate aggregate rich-list wealth totals and growth metrics.
Reports row counts, total current wealth, total last-year wealth, nominal
year-over-year growth, and CPI-adjusted growth. CPI adjustment uses the fixed
`CPI_YOY_PCT` constant (currently 4.6%) to inflation-adjust last year's wealth
before calculating adjusted growth.
Usage:
python3 calc_rich_totals.py
python3 calc_rich_totals.py --only-billionaires
Options:
--only-billionaires Include only rows where current wealth is at least $1B.
"""
from __future__ import annotations
import argparse
import csv
import re
from pathlib import Path
INPUT_CSV = Path("rich_list_table.csv")
BILLION_DOLLARS = 1_000_000_000.0
CPI_YOY_PCT = 4.6
MONEY_RE = re.compile(r"\$\s*([0-9][0-9,]*(?:\.[0-9]+)?)\s*([bm]?)", re.IGNORECASE)
UNIT_MULTIPLIER = {"": 1.0, "m": 1_000_000.0, "b": 1_000_000_000.0}
def parse_money(value: str) -> float | None:
match = MONEY_RE.search((value or "").strip())
if not match:
return None
amount = float(match.group(1).replace(",", ""))
unit = match.group(2).lower()
return amount * UNIT_MULTIPLIER[unit]
def format_number(value: float) -> str:
rounded = round(value, 2)
return f"{rounded:.2f}".rstrip("0").rstrip(".")
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Calculate aggregate wealth totals.")
parser.add_argument(
"--only-billionaires",
action="store_true",
help="Only include rows where current wealth is at least $1B.",
)
return parser.parse_args()
def main() -> None:
args = parse_args()
total_rows = 0
used_rows = 0
total_wealth = 0.0
total_wealth_last_year = 0.0
with INPUT_CSV.open(newline="", encoding="utf-8") as csv_file:
for row in csv.DictReader(csv_file):
total_rows += 1
wealth = parse_money(row.get("wealth", ""))
wealth_last_year = parse_money(row.get("wealth_last_year", ""))
if wealth is None or wealth_last_year is None:
continue
if args.only_billionaires and wealth < BILLION_DOLLARS:
continue
used_rows += 1
total_wealth += wealth
total_wealth_last_year += wealth_last_year
yoy_growth_pct = None
if total_wealth_last_year:
yoy_growth_pct = ((total_wealth - total_wealth_last_year) / total_wealth_last_year) * 100
total_wealth_b = total_wealth / BILLION_DOLLARS
total_wealth_last_year_b = total_wealth_last_year / BILLION_DOLLARS
total_growth_b = total_wealth_b - total_wealth_last_year_b
cpi_multiplier = 1 + (CPI_YOY_PCT / 100)
total_wealth_last_year_b_adjusted = total_wealth_last_year_b * cpi_multiplier
total_growth_b_adjusted = total_wealth_b - total_wealth_last_year_b_adjusted
yoy_growth_pct_adjusted = None
if total_wealth_last_year_b_adjusted:
yoy_growth_pct_adjusted = (total_growth_b_adjusted / total_wealth_last_year_b_adjusted) * 100
print(f"rows {total_rows}")
print(f"rows_excluded {total_rows - used_rows}")
print(f"total_wealth_b_dollars {format_number(total_wealth_b)}")
print(f"total_wealth_last_year_b_dollars {format_number(total_wealth_last_year_b)}")
print(f"total_wealth_last_year_b_dollars_adjusted {format_number(total_wealth_last_year_b_adjusted)}")
print(f"total_growth_b_dollars {format_number(total_growth_b)}")
print(f"total_growth_b_dollars_adjusted {format_number(total_growth_b_adjusted)}")
print(f"yoy_growth_pct {format_number(yoy_growth_pct) if yoy_growth_pct is not None else 'n/a'}")
print(
f"yoy_growth_pct_adjusted {format_number(yoy_growth_pct_adjusted) if yoy_growth_pct_adjusted is not None else 'n/a'}"
)
if __name__ == "__main__":
main()
> calc_rich_totals.py --only-billionaires
rows 200
rows_excluded 32
total_wealth_b_dollars 672.23
total_wealth_last_year_b_dollars 641.5
total_wealth_last_year_b_dollars_adjusted 671.01
total_growth_b_dollars 30.73
total_growth_b_dollars_adjusted 1.22
yoy_growth_pct 4.79
yoy_growth_pct_adjusted 0.18
name wealth wealth_last_year yoy_change
Gina Rinehart $39.01b $38.1b 2%
Harry Triguboff $32.28b $29.7b 9%
Anthony Pratt & family $25.19b $25.8b -3%
Ivan Glasenberg $22.38b $13.3b 68%
Clive Palmer $19.55b $20.1b -3%
Melanie Perkins & Cliff Obrecht $17.56b $14.1b 24%
Nicola Forrest $17.32b $12.8b 35%
Andrew Forrest $15.93b $12.7b 26%
Michael Dorrell $13.82b $13.9b 0%
Mario, Marcello & Adrian Verrocchi $12.76b $9.8b 30%
Jack, Sam & Damien Gance $12.34b $11.3b 10%
Kerry Stokes $12.33b $12.7b -3%
Scott Farquhar & Kim Jackson $11.70b $21.4b -45%
Frank Lowy $10.43b $10.3b 1%
Vivek Chaand Sehgal $9.64b $8.1b 20%
Angela Bennett $9.02b $8.4b 7%
Richard White $8.87b $10.6b -16%
Cameron Adams $8.77b $7.0b 26%
Alexandra Burt & Leonie Baldock $7.86b $7.2b 9%
John Gandel $7.68b $7.2b 7%
Annie Cannon-Brookes $6.71b $12.2b -45%
Mike Cannon-Brookes $6.71b $12.2b -45%
Sue Walker & family $6.43b $6.9b -7%
Len Ainsworth & family $6.23b $6.7b -7%
Alan Wilson & family $6.06b $6.1b 0%
Dennis Bastas $5.74b $2.9b 96%
Lindsay Fox $5.57b $5.7b -3%
Zac Fried, Morry Fraid & family $5.56b $5.0b 11%
Vikas Rambal $5.32b $5.0b 7%
James Packer $5.25b $5.0b 5%
Prudence MacLeod $5.23b $3.5b 49%
Ed Craven $5.20b $4.8b 8%
Greg Goodman & family $5.14b $4.7b 11%
Jack Cowin $4.63b $4.7b -1%
Brett Blundy $4.54b $4.0b 15%
Nick Wakim $4.36b $1.2b 274%
Laurence Escalante $4.35b $4.5b -3%
Gerry Harvey & Katie Page Harvey $4.33b $3.8b 13%
Michael Heine & family $4.20b $4.4b -4%
Michael Hodgson $4.07b $3.7b 9%
Sam Kennard & family $3.98b $3.8b 5%
Nick Politis $3.96b $2.6b 54%
Kie Chie Wong & family $3.96b $3.4b 16%
Solomon Lew $3.76b $4.1b -8%
Hui Wing Mau $3.74b $3.8b -2%
Anthony Hall $3.67b $5.1b -28%
Sam Hupert $3.60b $5.0b -28%
Lachlan Murdoch $3.52b $3.2b 9%
Sam Chong $3.50b $3.3b 6%
Sam Arnaout $3.47b $3.1b 13%
Manny Stul & family $3.45b $3.2b 8%
Betty Klimenko, Monica Saunders-Weinberg & family $3.29b $3.1b 6%
John Van Lieshout $3.24b $3.0b 7%
Chau Chak Wing $3.23b $3.7b -13%
Andrew Budzinski $3.19b $2.8b 13%
Tony Perich & family $3.09b $2.9b 8%
David & Vicky Teoh $3.06b $2.8b 10%
Paul Baiada & family $3.05b $2.7b 14%
Chris Thomas $2.99b $3.0b 1%
John & Michael Borg & family $2.93b $2.6b 14%
Bob Ell $2.88b $2.5b 16%
Bianca Rinehart $2.83b $2.7b 6%
Sam Alter & family $2.80b $2.7b 4%
Ginia Rinehart $2.78b $2.6b 5%
Hope Rinehart Welker $2.77b $2.6b 5%
Anthony El-Hazouri & Charbel Hazzouri $2.70b N/A N/A
Katrina Leslie $2.50b N/A N/A
John Hancock $2.49b $2.7b -7%
Jonathan Munz & family $2.48b $2.3b 10%
Gretel Packer $2.48b $2.3b 6%
Theo Andrianakos $2.48b $2.2b 13%
Robin Khuda $2.43b $2.1b 14%
Nigel Austin $2.42b $2.4b 0%
Eddie Hirsch $2.33b $2.3b 3%
Dick Honan $2.33b $2.4b -3%
Michael Hintze $2.32b $2.1b 9%
Avi Silver $2.31b $2.3b 3%
Alan Rydge $2.22b $2.1b 5%
John Richards & family $2.21b $1.9b 14%
Russell Withers & family $2.21b $2.1b 4%
Trevor Lee $2.20b $2.0b 10%
Joanna Horgan & Peter Wetenhall $2.17b $1.2b 74%
Paul Little $2.12b $2.3b -9%
Maha Sinnathamby $2.09b $2.0b 4%
Dale Elphinstone $2.08b $1.9b 7%
John Casella & family $2.07b $2.4b -13%
Paul Salteri & family $2.05b $2.0b 4%
Kerr Neilson $2.04b $1.7b 23%
Richard Gunn & Jackie Haintz & family $2.04b $2.0b 3%
Tim Roberts $2.03b $1.8b 14%
Naomi Milgrom $2.02b $1.7b 17%
Paul Lederer $2.01b $2.0b 2%
Sam Prince $1.97b $2.0b 0%
Arthur Laundy $1.95b $1.8b 11%
Khalil Shahin & family $1.93b $1.7b 11%
Chris Morris $1.93b $2.1b -9%
Imelda Roche $1.91b $1.8b 8%
Sandy Oatley & family $1.91b $1.8b 8%
Paul Tieck & family $1.90b $1.6b 19%
Russell & Kellie Wilson $1.87b $1.6b 16%
Craig, Lauren, Ryan Sutton & family $1.86b $1.7b 9%
Sam Tarascio $1.85b $1.8b 6%
Chris Wallin $1.84b $2.1b -10%
Bruce Mathieson $1.82b $1.3b 43%
Ralph & Patricia Sarich $1.82b $1.7b 6%
Andy Kennard & family $1.82b $1.6b 12%
Robert Millner & family $1.81b $1.6b 11%
Raymond & Rhonda Barro $1.78b $1.7b 3%
Ye Lipei $1.76b $1.7b 3%
Garry Tieck & family $1.75b $1.7b 3%
Robert Chamberlain $1.75b $1.2b 43%
Justin & Bettina Hemmes & family $1.71b $1.6b 8%
Peter Smaller $1.71b $1.7b 1%
Nick DiMauro $1.70b $1.4b 21%
Raphael Geminder $1.70b $1.7b 1%
Reg Rowe $1.69b $1.5b 13%
Chris Ellison $1.67b $871m 92%
Shaun Bonétt & family $1.67b $1.7b -2%
Nechama Werdiger & family $1.64b $1.6b 4%
Johnny & Markus Kahlbetzer & family $1.63b $1.5b 9%
Terry & Arthur Tzaneros $1.61b $1.7b -7%
Brian Flannery $1.60b $1.2b 34%
Nicholas Paspaley & family $1.60b $1.5b 5%
Denis Wagner & family $1.60b $1.1b 49%
Greg Coffey $1.59b $1.2b 28%
Jack Zhang $1.58b $1.3b 23%
Alex Waislitz & family $1.58b $1.6b 2%
Ginette Snow & family $1.56b $1.5b 7%
Charlotte Vidor $1.54b $1.5b 6%
Roger & Gail Fletcher & family $1.52b $1.5b 4%
Marnie Lewis-Millar & Shay Lewis & family $1.50b $1.4b 7%
Lyn Ingham & family $1.47b $1.4b 8%
Tim Heath $1.45b $2.5b -41%
Adrian Portelli $1.44b $1.4b 2%
Larry Kestelman $1.38b $1.4b 2%
Ian Malouf $1.38b $1.3b 6%
James & Robert Ferguson $1.33b $1.7b -20%
Harry Stamoulis & family $1.33b $1.2b 13%
Peter Scanlon & family $1.32b N/A 3%
Daniel & Georgia Contos & family $1.31b N/A N/A
Ryan & Sam Kroonenburg $1.29b $1.2b 4%
Adrian & Peter Puljich & family $1.26b N/A N/A
Greg Karedis & family $1.26b $1.2b 5%
Arnold Vitocco $1.26b $1.2b 9%
Mark Creasy $1.25b $859m 46%
Oliver Curtis $1.25b N/A N/A
Max Beck $1.25b $1.2b 3%
Bruce Gordon $1.24b $1.2b 7%
Pamela Wall $1.22b N/A N/A
Rod Spooner & family $1.22b $1.2b 2%
Balfour & Nicola Irvine $1.21b N/A N/A
Judith Neilson $1.21b $1.2b -2%
Peter Freedman $1.20b $1.2b -2%
Mick & Denise Power $1.18b $984m 20%
Nick Molnar $1.18b $1.1b 6%
Anthony Eisen $1.16b N/A 3%
Kevin Seymour & family $1.15b $794m 45%
Will Vicars $1.14b $1.1b 1%
Tim Gurner $1.14b $995m 15%
Rod Duke $1.14b $1.1b 3%
Carol & Alan Schwartz $1.13b $1.0b 11%
Neville Crichton $1.13b $1.1b -1%
Huang Bingwen & family $1.12b $951m 18%
Sam Buckeridge & family $1.11b $1.1b 5%
Shirley Costa & family $1.09b $1.0b 5%
Lloyd Williams $1.08b $1.0b 5%
Robyn Denholm $1.08b $952m 14%
Robert Whyte $1.08b $1.1b 2%
Spiros Alysandratos $1.07b $1.1b -5%
Roy Medich $1.07b $1.0b 5%
Richard Smith $1.07b $1.0b 6%
Daniel Besen $1.05b $1.0b 4%
Diane Burger & family $1.05b $907m 16%
Simon Dyer & family $1.05b $1.1b -6%
Shirley Uhrig & family $1.04b N/A N/A
Con Makris & family $1.03b $987m 5%
Gordon Fu & family $1.03b $1.6b 15%
Charles Gibbon $1.03b $1.6b -34%
Marco Rossi $997m N/A N/A
Neil Rae & family $983m $940m 5%
Margaret Dymond & family $976m $785m 24%
Allan Myers $975m $939m 4%
Peter Hughes & family $972m $927m 5%
Ilias Pavlopoulos, Andrew Chepul & family $944m $883m 7%
Jacob Dai $923m N/A N/A
Robert Magid $907m $872m 4%
Rhonda Wyllie & family $905m $837m 8%
Don McDonald & family $901m $861m 5%
Andre & Carole Estephan $901m N/A N/A
Robin Murphy & family $900m $823m 9%
Tony Walls $892m $983m -9%
Geoff Wilson $891m N/A N/A
Robert Hilmer $888m N/A N/A
Anthony Woods $881m N/A N/A
Zareh Nalbandian $872m $840m 4%
John Winning & family $860m $798m 8%
Shane & David Young $858m $839m 2%
Matthew Latimore $857m $748m 15%
Tim Goyder $855m N/A N/A
Daniel Roberts & William Roberts $853m N/A N/A
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment