81 lines
2.5 KiB
Python
81 lines
2.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Structural verifier for the countries extraction table.
|
|
|
|
Usage:
|
|
python3 check_countries.py <csv_path> <expected_rows>
|
|
|
|
Exits 0 iff the CSV satisfies the contract:
|
|
- header is exactly the 14-column contract (see HEADERS)
|
|
- every data row has exactly 14 fields
|
|
- alpha-2 codes are unique and there are exactly expected_rows rows
|
|
|
|
Exits 1 with a detailed message otherwise. The exit code IS the verdict:
|
|
0 = correct, nonzero = wrong.
|
|
"""
|
|
import csv
|
|
import sys
|
|
|
|
EXPECTED_HEADER = [
|
|
'name_common', 'name_official', 'alpha2', 'alpha3', 'numeric',
|
|
'region', 'subregion', 'capital', 'population', 'area_km2',
|
|
'currencies', 'languages', 'tlds', 'flag',
|
|
]
|
|
|
|
|
|
def main():
|
|
if len(sys.argv) != 3:
|
|
sys.stderr.write('usage: check_countries.py <csv_path> <expected_rows>\n')
|
|
return 2
|
|
csv_path, expected_raw = sys.argv[1], sys.argv[2]
|
|
try:
|
|
expected = int(expected_raw)
|
|
except ValueError:
|
|
sys.stderr.write('expected_rows must be an integer\n')
|
|
return 2
|
|
try:
|
|
fh = open(csv_path, encoding='utf-8')
|
|
except OSError as exc:
|
|
sys.stderr.write('cannot open %s: %s\n' % (csv_path, exc))
|
|
return 1
|
|
|
|
with fh:
|
|
reader = csv.reader(fh)
|
|
try:
|
|
header = next(reader)
|
|
except StopIteration:
|
|
sys.stderr.write('CSV is empty\n')
|
|
return 1
|
|
if header != EXPECTED_HEADER:
|
|
sys.stderr.write('bad header: %r\n' % header)
|
|
return 1
|
|
rows = list(reader)
|
|
codes = []
|
|
for index, row in enumerate(rows, start=2):
|
|
if len(row) != len(EXPECTED_HEADER):
|
|
sys.stderr.write('row %d has %d fields (expected %d)\n'
|
|
% (index, len(row), len(EXPECTED_HEADER)))
|
|
return 1
|
|
codes.append(row[2])
|
|
seen = set()
|
|
duplicates = []
|
|
for code in codes:
|
|
if code in seen:
|
|
duplicates.append(code)
|
|
seen.add(code)
|
|
|
|
ok = True
|
|
if len(rows) != expected:
|
|
sys.stderr.write('row count %d != expected %d\n'
|
|
% (len(rows), expected))
|
|
ok = False
|
|
if duplicates:
|
|
sys.stderr.write('duplicate alpha-2 codes: %r\n' % sorted(duplicates))
|
|
ok = False
|
|
print('rows=%d fields=%d unique_alpha2=%d header_ok=True'
|
|
% (len(rows), len(header), len(seen)))
|
|
return 0 if ok else 1
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|