fix(api): map blank-name GIAS sentinel codes to empty string, not Unknown
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m40s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 20s
PR Checks / Build Frontend (no push) (pull_request) Successful in 54s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 37s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 2m35s
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 9m40s
PR Checks / Backend Smoke (pull_request) Successful in 7s
PR Checks / Build Backend (no push) (pull_request) Successful in 20s
PR Checks / Build Frontend (no push) (pull_request) Successful in 54s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 37s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 2m35s
ReligiousCharacter 99 (~4k schools) and AdmissionsPolicy 9 (~5.6k) carry a code with a blank name in the GIAS CSV; the generator skipped them so they hit the Unknown(<code>) path — wrongly triggering the Faith-priority tag and polluting filters. Blank-only codes now map to "" (byte-identical to the old name pipeline); accepted_values lists extended to match the seed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -94,13 +94,23 @@ def main() -> None:
|
||||
for code_col, name_col, dict_name, field_key in FIELDS:
|
||||
pairs = (
|
||||
df[[code_col, name_col]]
|
||||
.loc[lambda d: (d[code_col] != "") & (d[name_col] != "")]
|
||||
.loc[lambda d: d[code_col] != ""]
|
||||
.drop_duplicates()
|
||||
)
|
||||
mapping = sorted((int(c), n) for c, n in pairs.itertuples(index=False))
|
||||
dupes = len(mapping) - len({c for c, _ in mapping})
|
||||
if dupes:
|
||||
sys.exit(f"{code_col}: {dupes} codes map to multiple names — investigate before generating")
|
||||
by_code: dict[int, set] = {}
|
||||
for c, n in pairs.itertuples(index=False):
|
||||
by_code.setdefault(int(c), set()).add(n)
|
||||
mapping = []
|
||||
for code, names in sorted(by_code.items()):
|
||||
named = sorted(n for n in names if n != "")
|
||||
if len(named) > 1:
|
||||
sys.exit(f"{code_col}: code {code} maps to multiple names {named} — investigate before generating")
|
||||
# Codes that only ever appear with a blank (name) are GIAS
|
||||
# "not recorded" sentinels (e.g. ReligiousCharacter 99,
|
||||
# AdmissionsPolicy 9). Map them to "" so the API serves the same
|
||||
# empty string the old name pipeline did — the "Unknown (<code>)"
|
||||
# path is reserved for genuinely new codes.
|
||||
mapping.append((code, named[0] if named else ""))
|
||||
lines = [f"{dict_name}: dict[int, str] = {{"]
|
||||
for code, name in mapping:
|
||||
escaped = name.replace('"', '\\"')
|
||||
|
||||
@@ -78,6 +78,7 @@ OFFICIAL_SIXTH_FORM: dict[int, str] = {
|
||||
0: "Not applicable",
|
||||
1: "Has a sixth form",
|
||||
2: "Does not have a sixth form",
|
||||
9: "",
|
||||
}
|
||||
|
||||
RELIGIOUS_CHARACTER: dict[int, str] = {
|
||||
@@ -128,12 +129,14 @@ RELIGIOUS_CHARACTER: dict[int, str] = {
|
||||
47: "Reformed Baptist",
|
||||
48: "Roman Catholic/Anglican",
|
||||
49: "Sunni Deobandi",
|
||||
99: "",
|
||||
}
|
||||
|
||||
ADMISSIONS_POLICY: dict[int, str] = {
|
||||
0: "Not applicable",
|
||||
2: "Selective",
|
||||
4: "Non-selective",
|
||||
9: "",
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user