ledger: GDP (nominal, current US$) top-20 countries 2023 from World Bank API
This commit is contained in:
1 parent
3f389acf3c
commit
d2964cd4af
6 files changed
+461
No files matched your search
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Extract GDP (nominal, current US$) for the top 20 countries, 2023.
|
||||
|
||||
Source: World Bank API, indicator NY.GDP.MKTP.CD (GDP, current US$), country:all, date=2023.
|
||||
Filter: keep only records whose country.id is a real ISO 3166-1 alpha-3 code
|
||||
(iso3_codes.txt from the Wikipedia ISO3 list), dropping World Bank aggregates.
|
||||
Artifacts (written alongside this script):
|
||||
- gdp_nominal_usd_2023.csv (rank, country, iso3, gdp_nominal_usd_billions)
|
||||
- gdp_nominal_usd_2023.md (markdown table of the same top-20)
|
||||
"""
|
||||
import csv
|
||||
import json
|
||||
import os
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
ISO3_PATH = os.path.join(HERE, "iso3_codes.txt")
|
||||
JSON_PATH = os.path.join(HERE, "gdp_nominal_usd_2023.json")
|
||||
CSV_PATH = os.path.join(HERE, "gdp_nominal_usd_2023.csv")
|
||||
MD_PATH = os.path.join(HERE, "gdp_nominal_usd_2023.md")
|
||||
TOP_N = 20
|
||||
|
||||
with open(ISO3_PATH, "r", encoding="utf-8") as f:
|
||||
iso3_codes = set(line.strip() for line in f if line.strip())
|
||||
|
||||
with open(JSON_PATH, "r", encoding="utf-8") as f:
|
||||
payload = json.load(f)
|
||||
|
||||
records = payload[1] # payload[0] is the metadata envelope
|
||||
rows = []
|
||||
for r in records:
|
||||
country = r.get("country", {})
|
||||
value = r.get("value")
|
||||
code = r.get("countryiso3code") # ISO 3166-1 alpha-3; aggregates use non-ISO codes
|
||||
if value is None or code not in iso3_codes:
|
||||
continue
|
||||
rows.append(
|
||||
{
|
||||
"country": country.get("value", ""),
|
||||
"iso3": code,
|
||||
"gdp_raw_usd": float(value),
|
||||
}
|
||||
)
|
||||
|
||||
rows.sort(key=lambda x: -x["gdp_raw_usd"])
|
||||
top = rows[:TOP_N]
|
||||
|
||||
with open(CSV_PATH, "w", newline="", encoding="utf-8") as f:
|
||||
writer = csv.writer(f)
|
||||
writer.writerow(["rank", "country", "iso3", "gdp_nominal_usd_billions"])
|
||||
for i, r in enumerate(top, 1):
|
||||
writer.writerow([i, r["country"], r["iso3"], round(r["gdp_raw_usd"] / 1e9, 3)])
|
||||
|
||||
lines = [
|
||||
"# Top 20 countries by GDP (nominal, current US$) — 2023",
|
||||
"",
|
||||
"Source: World Bank API (`NY.GDP.MKTP.CD`, 2023). Only ISO 3166-1 alpha-3 countries "
|
||||
"are counted (World Bank aggregates excluded).",
|
||||
"",
|
||||
"| Rank | Country | ISO3 | GDP nominal (USD billions) |",
|
||||
"|---:|---|:--:|---:|",
|
||||
]
|
||||
for i, r in enumerate(top, 1):
|
||||
lines.append(f"| {i} | {r['country']} | {r['iso3']} | {r['gdp_raw_usd'] / 1e9:.3f} |")
|
||||
|
||||
with open(MD_PATH, "w", encoding="utf-8") as f:
|
||||
f.write("\n".join(lines) + "\n")
|
||||
|
||||
print(f"PARSED rows={len(rows)} kept_countries={len(top)}")
|
||||
for r in top:
|
||||
print(f" {r['country']} ({r['iso3']}) {r['gdp_raw_usd'] / 1e9:.3f}B")
|
||||
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Real cross-check: re-fetches the World Bank GDP nominal-2023 API and compares the
|
||||
committed gdp_nominal_usd_2023.csv (next to this script) against a fresh computation.
|
||||
|
||||
Exit code: 0 = artifact matches the live source of truth; 1 = mismatch.
|
||||
"""
|
||||
import csv
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import urllib.request
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
CSV_PATH = os.path.join(HERE, "gdp_nominal_usd_2023.csv")
|
||||
ISO3_PATH = os.path.join(HERE, "iso3_codes.txt")
|
||||
|
||||
API_URL = ("https://api.worldbank.org/v2/country/all/indicator/NY.GDP.MKTP.CD"
|
||||
"?format=json&date=2023:2023&per_page=1000")
|
||||
TOLERANCE_USD = 1_000_000 # 1e6 USD == 0.001B (artifact rounds to 3 decimals)
|
||||
|
||||
|
||||
def fetch_json(url):
|
||||
req = urllib.request.Request(url, headers={"User-Agent": "ledger/extract/1.0"})
|
||||
with urllib.request.urlopen(req, timeout=40) as r:
|
||||
return json.loads(r.read().decode("utf-8"))
|
||||
|
||||
|
||||
def main():
|
||||
with open(ISO3_PATH, encoding="utf-8") as f:
|
||||
iso3 = {ln.strip() for ln in f if ln.strip()}
|
||||
|
||||
payload = fetch_json(API_URL)
|
||||
records = payload[1] if isinstance(payload, list) and payload else []
|
||||
api = []
|
||||
for rec in records:
|
||||
iso = rec.get("countryiso3code")
|
||||
val = rec.get("value")
|
||||
if iso in iso3 and val is not None:
|
||||
api.append((rec["country"]["value"], iso, float(val)))
|
||||
api.sort(key=lambda x: -x[2])
|
||||
top20 = api[:20]
|
||||
|
||||
with open(CSV_PATH, encoding="utf-8") as f:
|
||||
rows = [r for r in csv.reader(f) if r]
|
||||
if not rows:
|
||||
print("FAIL: artifact CSV is empty")
|
||||
sys.exit(1)
|
||||
data = rows[1:]
|
||||
|
||||
if len(data) != 20:
|
||||
print(f"FAIL: artifact has {len(data)} data rows, expected 20")
|
||||
sys.exit(1)
|
||||
|
||||
ok = True
|
||||
for i, (cname, ciso, cval) in enumerate(top20):
|
||||
row = data[i]
|
||||
try:
|
||||
artifact_usd = float(row[3]) * 1e9
|
||||
except (ValueError, IndexError):
|
||||
artifact_usd = None
|
||||
good = (row[1] == cname) and (row[2] == ciso) and (artifact_usd is not None
|
||||
and abs(artifact_usd - cval) < TOLERANCE_USD)
|
||||
if not good:
|
||||
ok = False
|
||||
print(f"MISMATCH rank {i+1}: source={cname} {ciso} {cval:.3f}B; "
|
||||
f"artifact={row}")
|
||||
|
||||
values = [float(r[3]) for r in data]
|
||||
if values != sorted(values, reverse=True):
|
||||
ok = False
|
||||
print("FAIL: artifact rows are not in descending GDP order")
|
||||
|
||||
if ok:
|
||||
print(f"CHECK OK: {len(top20)} countries match the live World Bank API "
|
||||
f"(US={top20[0][1]}, China={top20[1][1]}).")
|
||||
sys.exit(0)
|
||||
print("CHECK FAIL")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,21 @@
|
||||
rank,country,iso3,gdp_nominal_usd_billions
|
||||
1,United States,USA,27811.517
|
||||
2,China,CHN,18270.357
|
||||
3,Germany,DEU,4562.208
|
||||
4,Japan,JPN,4384.854
|
||||
5,India,IND,3500.906
|
||||
6,United Kingdom,GBR,3420.797
|
||||
7,France,FRA,3056.251
|
||||
8,Italy,ITA,2316.882
|
||||
9,Canada,CAN,2196.594
|
||||
10,Brazil,BRA,2191.132
|
||||
11,Russian Federation,RUS,2046.285
|
||||
12,"Korea, Rep.",KOR,1844.801
|
||||
13,Mexico,MEX,1794.41
|
||||
14,Australia,AUS,1734.451
|
||||
15,Spain,ESP,1619.482
|
||||
16,Indonesia,IDN,1371.167
|
||||
17,Saudi Arabia,SAU,1218.585
|
||||
18,Turkiye,TUR,1141.243
|
||||
19,Netherlands,NLD,1135.476
|
||||
20,Switzerland,CHE,928.435
|
||||
|
@@ -0,0 +1 @@
|
||||
[{"page":1,"pages":1,"per_page":1000,"total":266,"sourceid":"2","lastupdated":"2026-10-08"},[{"indicator":{"id":"NY.GDP.MKTP.CD","value":"GDP (current US$)"},"country":{"id":"ZH","value":"Africa Eastern and Southern"},"countryiso3code":"AFE","date":"2023","value":1179121535535.41,"unit":"","obs_status":"","decimal":0},{"indicator":{"id":"NY.GDP.MKTP.CD","value":"GDP (current US$)"},"country":{"id":"ZI","value":"Africa Western and Central"},"countryiso3code":"AFW","date":"2023","value":938480674635.085,"unit":"","obs_status":"","decimal":0},{"indicator":{"id":"NY.GDP.MKTP.CD","value":"GDP (current US$)"},"country":{"id":"1A","value":"Arab World"},"countryiso3code":"ARB","date":"2023","value":3617895070373.04,"unit":"","obs_status":"","decimal":0},{"indicator":{"id":"NY.GDP.MKTP.CD","value":"GDP (current US$)"},"country":{"id":"S3","value":"Caribbean small states"},"countryiso3code":"CSS","date":"2023","value":79594075306.6477,"unit":"","obs_status":"","decimal":0},{"indicator":{"id":"NY.GDP.MKTP.CD","value":"GDP (current US$)"},"country":{"id":"B8","value":"Central Europe and the Baltics"},"countryiso3code":"CEB","date":"2023","value":2273564082260.43,"unit":"","obs_status":"","decimal":0},{"indicator":{"id":"NY.GDP.MKTP.CD","value":"GDP (current US$)"},"country":{"id":"V2","value":"Early-demographic dividend"},"countryiso3code":"EAR","date":"2023","value":14791485754640,"unit":"","obs_status":"","decimal":0},{"indicator":{"id":"NY.GDP.MKTP.CD","value":"GDP (current US$)"},"country":{"id":"Z4","value":"East Asia & Pacific"},"countryiso3code":"EAS","date":"2023","value":31597454903562.8,"unit":"","obs_status":"","decimal":0},{"indicator":{"id":"NY.GDP.MKTP.CD","value":"GDP (current US$)"},"country":{"id":"4E","value":"East Asia & Pacific (excluding high income)"},"countryiso3code":"EAP","date":"2023","value":21645526054900.4,"unit":"","obs_status":"","decimal":0},{"indicator":{"id":"NY.GDP.MKTP.CD","value":"GDP (current US$)"},"country":{"id":"T4","value":"East Asia & Pacific (IDA & IBRD countries)"},"countryiso3code":"TEA","date":"2023","value":21618798469116.4,"unit":"","obs_status":"","decimal":0},{"indicator":{"id":"NY.GDP.MKTP.CD","value":"GDP (current US$)"},"country":{"id":"XC","value":"Euro area"},"countryiso3code":"EMU","date":"2023","value":15957338405375.8,"unit":"","obs_status":"","decimal":0},{"indicator":{"id":"NY.GDP.MKTP.CD","value":"GDP (current US$)"},"country":{"id":"Z7","value":"Europe & Central Asia"},"countryiso3code":"ECS","date":"2023","value":27758730809930.4,"unit":"","obs_status":"","decimal":0},{"indicator":{"id":"NY.GDP.MKTP.CD","value":"GDP (current US$)"},"country":{"id":"7E","value":"Europe & Central Asia (excluding high income)"},"countryiso3code":"ECA","date":"2023","value":2141252006536.72,"unit":"","obs_status":"","decimal":0},{"indicator":{"id":"NY.GDP.MKTP.CD","value":"GDP (current US$)"},"country":{"id":"T7","value":"Europe & Central Asia (IDA & IBRD countries)"},"countryiso3code":"TEC","date":"2023","value":5535571828711.02,"unit":"","obs_status":"","decimal":0},{"indicator":{"id":"NY.GDP.MKTP.CD","value":"GDP (current US$)"},"country":{"id":"EU","value":"European Union"},"countryiso3code":"EUU","date":"2023","value":18659279022583.3,"unit":"","obs_status":"","decimal":0},{"indicator":{"id":"NY.GDP.MKTP.CD","value":"GDP (current US$)"},"country":{"id":"F2","value":"Fragility, Conflict, and Violence (FCV) situations"},"countryiso3code":"FCV","date":"2023","value":2043142894382.41,"unit":"","obs_status":"","decimal":0},{"indicator":{"id":"NY.GDP.MKTP.CD","value":"GDP (current US$)"},"country":{"id":"XE","value":"Heavily indebted poor countries (HIPC)"},"countryiso3code":"HPC","date":"2023","value":1060851525652.8,"unit":"","obs_status":"","decimal":0},{"indicator":{"id":"NY.GDP.MKTP.CD","value":"GDP (current US$)"},"country":{"id":"XD","value":"High income"},"countryiso3code":"","date":"2023","value":69198099195981.1,"unit":"","obs_status":"","decimal":0},{"indicator":{"id":"NY.GDP.MKTP.CD","value":"GDP (current US$)"},"country":{"id":"XF","value":"IBRD only"},"countryiso3code":"IBD","date":"2023","value":39083500948084.9,"unit":"","obs_status":"","decimal":0},{"indicator":{"id":"NY.GDP.MKTP.CD","value":"GDP (current US$)"},"country":{"id":"ZT","value":"IDA & IBRD total"},"countryiso3code":"IBT","date":"2023","value":42011330091982.8,"unit":"","obs_status":"","decimal":0},{"indicator":{"id":"NY.GDP.MKTP.CD","value":"GDP (current US$)"},"country":{"id":"XH","value":"IDA blend"},"countryiso3code":"IDB","date":"2023","value":1277421993702.09,"unit":"","obs_status":"","decimal":0},{"indicator":{"id":"NY.GDP.MKTP.CD","value":"GDP (current US$)"},"country":{"id":"XI","value":"IDA only"},"countryiso3code":"IDX","date":"2023","value":1650407150195.89,"unit":"","obs_status":"","decimal":0},{"indicator":{"id":"NY.GDP.MKTP.CD","value":"GDP (current US$)"},"country":{"id":"XG","value":"IDA total"},"countryiso3code":"IDA","date":"2023","value":2927829143897.98,"unit":"","obs_status":Line truncated
|
||||
@@ -0,0 +1,26 @@
|
||||
# Top 20 countries by GDP (nominal, current US$) — 2023
|
||||
|
||||
Source: World Bank API (`NY.GDP.MKTP.CD`, 2023). Only ISO 3166-1 alpha-3 countries are counted (World Bank aggregates excluded).
|
||||
|
||||
| Rank | Country | ISO3 | GDP nominal (USD billions) |
|
||||
|---:|---|:--:|---:|
|
||||
| 1 | United States | USA | 27811.517 |
|
||||
| 2 | China | CHN | 18270.357 |
|
||||
| 3 | Germany | DEU | 4562.208 |
|
||||
| 4 | Japan | JPN | 4384.854 |
|
||||
| 5 | India | IND | 3500.906 |
|
||||
| 6 | United Kingdom | GBR | 3420.797 |
|
||||
| 7 | France | FRA | 3056.251 |
|
||||
| 8 | Italy | ITA | 2316.882 |
|
||||
| 9 | Canada | CAN | 2196.594 |
|
||||
| 10 | Brazil | BRA | 2191.132 |
|
||||
| 11 | Russian Federation | RUS | 2046.285 |
|
||||
| 12 | Korea, Rep. | KOR | 1844.801 |
|
||||
| 13 | Mexico | MEX | 1794.410 |
|
||||
| 14 | Australia | AUS | 1734.451 |
|
||||
| 15 | Spain | ESP | 1619.482 |
|
||||
| 16 | Indonesia | IDN | 1371.167 |
|
||||
| 17 | Saudi Arabia | SAU | 1218.585 |
|
||||
| 18 | Turkiye | TUR | 1141.243 |
|
||||
| 19 | Netherlands | NLD | 1135.476 |
|
||||
| 20 | Switzerland | CHE | 928.435 |
|
||||
@@ -0,0 +1,261 @@
|
||||
ABW
|
||||
AFG
|
||||
AGO
|
||||
AIA
|
||||
ALA
|
||||
ALB
|
||||
AND
|
||||
ARE
|
||||
ARG
|
||||
ARM
|
||||
ASM
|
||||
ATA
|
||||
ATF
|
||||
ATG
|
||||
AUS
|
||||
AUT
|
||||
AZE
|
||||
BDI
|
||||
BEL
|
||||
BEN
|
||||
BES
|
||||
BFA
|
||||
BGD
|
||||
BGR
|
||||
BHR
|
||||
BHS
|
||||
BIH
|
||||
BLM
|
||||
BLR
|
||||
BLZ
|
||||
BMU
|
||||
BOL
|
||||
BRA
|
||||
BRB
|
||||
BRN
|
||||
BTN
|
||||
BVT
|
||||
BWA
|
||||
CAF
|
||||
CAN
|
||||
CCK
|
||||
CHE
|
||||
CHL
|
||||
CHN
|
||||
CIV
|
||||
CMR
|
||||
COD
|
||||
COG
|
||||
COK
|
||||
COL
|
||||
COM
|
||||
CPV
|
||||
CRI
|
||||
CUB
|
||||
CUW
|
||||
CXR
|
||||
CYM
|
||||
CYP
|
||||
CZE
|
||||
DEU
|
||||
DJI
|
||||
DMA
|
||||
DNK
|
||||
DOM
|
||||
DZA
|
||||
ECU
|
||||
EGY
|
||||
ERI
|
||||
ESH
|
||||
ESP
|
||||
EST
|
||||
ETH
|
||||
FIN
|
||||
FJI
|
||||
FLK
|
||||
FRA
|
||||
FRO
|
||||
FSM
|
||||
GAB
|
||||
GBR
|
||||
GEO
|
||||
GGY
|
||||
GHA
|
||||
GIB
|
||||
GIN
|
||||
GLP
|
||||
GMB
|
||||
GNB
|
||||
GNQ
|
||||
GRC
|
||||
GRD
|
||||
GRL
|
||||
GTM
|
||||
GUF
|
||||
GUM
|
||||
GUY
|
||||
HKG
|
||||
HMD
|
||||
HND
|
||||
HRV
|
||||
HTI
|
||||
HUN
|
||||
IDN
|
||||
IMN
|
||||
IND
|
||||
IOT
|
||||
IRL
|
||||
IRN
|
||||
IRQ
|
||||
ISL
|
||||
ISR
|
||||
ITA
|
||||
JAM
|
||||
JEY
|
||||
JOR
|
||||
JPN
|
||||
KAZ
|
||||
KEN
|
||||
KGZ
|
||||
KHM
|
||||
KIR
|
||||
KNA
|
||||
KOR
|
||||
KWT
|
||||
LAO
|
||||
LBN
|
||||
LBR
|
||||
LBY
|
||||
LCA
|
||||
LIE
|
||||
LKA
|
||||
LSO
|
||||
LTU
|
||||
LUX
|
||||
LVA
|
||||
MAC
|
||||
MAF
|
||||
MAR
|
||||
MCO
|
||||
MDA
|
||||
MDG
|
||||
MDV
|
||||
MEX
|
||||
MHL
|
||||
MKD
|
||||
MLI
|
||||
MLT
|
||||
MMR
|
||||
MNE
|
||||
MNG
|
||||
MNP
|
||||
MOZ
|
||||
MRT
|
||||
MSR
|
||||
MTQ
|
||||
MUS
|
||||
MWI
|
||||
MYS
|
||||
MYT
|
||||
NAM
|
||||
NCL
|
||||
NER
|
||||
NFK
|
||||
NGA
|
||||
NIC
|
||||
NIU
|
||||
NLD
|
||||
NOR
|
||||
NPL
|
||||
NRU
|
||||
NZL
|
||||
OMN
|
||||
PAK
|
||||
PAN
|
||||
PCN
|
||||
PER
|
||||
PHL
|
||||
PLW
|
||||
PNG
|
||||
POL
|
||||
PRI
|
||||
PRK
|
||||
PRT
|
||||
PRY
|
||||
PSE
|
||||
PYF
|
||||
QAT
|
||||
REU
|
||||
ROU
|
||||
RUS
|
||||
RWA
|
||||
SAU
|
||||
SDN
|
||||
SEN
|
||||
SGP
|
||||
SGS
|
||||
SHN
|
||||
SJM
|
||||
SLB
|
||||
SLE
|
||||
SLV
|
||||
SMR
|
||||
SOM
|
||||
SPM
|
||||
SRB
|
||||
SSD
|
||||
STP
|
||||
SUR
|
||||
SVK
|
||||
SVN
|
||||
SWE
|
||||
SWZ
|
||||
SXM
|
||||
SYC
|
||||
SYR
|
||||
TCA
|
||||
TCD
|
||||
TGO
|
||||
THA
|
||||
TJK
|
||||
TKL
|
||||
TKM
|
||||
TLS
|
||||
TON
|
||||
TTO
|
||||
TUN
|
||||
TUR
|
||||
TUV
|
||||
TWN
|
||||
TZA
|
||||
UGA
|
||||
UKR
|
||||
UMI
|
||||
URY
|
||||
USA
|
||||
UZB
|
||||
VAT
|
||||
VCT
|
||||
VEN
|
||||
VGB
|
||||
VIR
|
||||
VNM
|
||||
VUT
|
||||
WLF
|
||||
WSM
|
||||
XXB
|
||||
XXE
|
||||
XXG
|
||||
XXI
|
||||
XXL
|
||||
XXM
|
||||
XXN
|
||||
XXP
|
||||
XXR
|
||||
XXS
|
||||
XXW
|
||||
XXY
|
||||
YEM
|
||||
ZAF
|
||||
ZMB
|
||||
ZWE
|
||||
Reference in new issue
Block a user