94 lines
4.2 KiB
Python
94 lines
4.2 KiB
Python
"""Verified CRZP workplace codes (the numbers after the school name).
|
|
|
|
CRZP writes a TUKE work as "Technická univerzita v Košiciach 1040 104005" and
|
|
does not publish what the codes mean. Only codes supported by the records are
|
|
named here:
|
|
- 104005 = KEMT: the works supervised by KEMT staff known from ZP Wiki
|
|
(Hládek, Staš, Ondáš, Pleva, Juhár, Galajda, Drutarovský, Čižmár, Viszlay)
|
|
carry 104005 in CRZP (checked on 2026-11-14 over the cached records, e.g.
|
|
Hládek 69 of 71, Staš 33 of 33, Ondáš 30 of 31);
|
|
- 1040 = FEI: every 104005 record starts with 1040 and KEMT belongs to FEI
|
|
(the ZP Wiki domain is zp.kemt.fei.tuke.sk).
|
|
Older records (about until 2015) write the department by name ("1040 Katedra
|
|
elektroniky a multimediálnych telekomunikácií") instead of 104005; CRZP indexes
|
|
that text too, so a workplace is searched by every form in "search" and the
|
|
name is matched as written.
|
|
Other TUKE department codes are named only when workplaces.json holds a name
|
|
learned from CRZP records with enough votes (see workplaces.py); such a
|
|
workplace can be asked by its acronym ("na KPI") or name and is searched by
|
|
its code and its old written name. Codes without evidence stay numbers
|
|
("pracovisko 104009"), never guessed.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
|
|
from tools.crzp.answering import workplaces
|
|
from tools.crzp.source.parse import fold
|
|
|
|
VERIFIED = {
|
|
"kemt": {"school": "tuke", "code": "104005", "label": "KEMT FEI",
|
|
"text": "katedra elektroniky a multimedialnych telekomunikacii",
|
|
"search": ["104005", "Katedra elektroniky a multimediálnych telekomunikácií"]},
|
|
"fei": {"school": "tuke", "code": "1040", "label": "FEI", "text": "fakulta elektrotechniky a informatiky",
|
|
"search": ["1040"]}, # old FEI records also start with 1040
|
|
}
|
|
CUES = {
|
|
"kemt": r"\bkemt\b|katedr\w* elektroniky a multimedi",
|
|
"fei": r"\bfei\b|fakult\w* elektrotechniky a informatiky",
|
|
}
|
|
|
|
|
|
def _learned_units() -> dict:
|
|
"""Departments named in workplaces.json, keyed by their acronym ("kpi")."""
|
|
units = {}
|
|
for short, (code, entry) in workplaces.by_acronym(workplaces.TUKE).items():
|
|
if short in VERIFIED or code in {u["code"] for u in VERIFIED.values()}:
|
|
continue
|
|
units[short] = {"school": "tuke", "code": code, "label": f"{entry['short']} FEI" if code.startswith("1040")
|
|
else entry["short"], "text": fold(entry["name"]), "search": [code, entry["name"]],
|
|
"learned": True}
|
|
words = [w for w in fold(entry["name"]).split() if w not in workplaces.SMALL_WORDS]
|
|
CUES[short] = r"\b" + re.escape(short) + r"\b|" + r"\w*\s+(?:\w+\s+)?".join(re.escape(w[:5]) for w in words)
|
|
return units
|
|
|
|
|
|
UNITS = {**VERIFIED, **_learned_units()}
|
|
ORDER = ["kemt", *[k for k in UNITS if UNITS[k].get("learned")], "fei"] # the most specific unit first
|
|
|
|
|
|
def unit_in_question(question: str) -> str | None:
|
|
"""The most specific known unit the question names (a department before FEI)."""
|
|
low = fold(question)
|
|
return next((key for key in ORDER if re.search(fold(CUES[key]) if key in ("kemt", "fei") else CUES[key], low)), None)
|
|
|
|
|
|
def _tuke(row: dict) -> bool:
|
|
return fold(row.get("school") or "") == "technicka univerzita v kosiciach"
|
|
|
|
|
|
def in_unit(row: dict, key: str) -> bool:
|
|
unit = row.get("school_unit") or ""
|
|
if not _tuke(row):
|
|
return False
|
|
if key == "fei" and in_unit(row, "kemt"):
|
|
return True
|
|
return UNITS[key]["code"] in unit.split() or UNITS[key]["text"] in fold(unit)
|
|
|
|
|
|
def unit_label(row: dict) -> str:
|
|
""""FEI, KEMT" for verified codes; unverified codes stay as "pracovisko 104009";
|
|
a department written by name is kept as written."""
|
|
unit = row.get("school_unit") or ""
|
|
if not unit or not _tuke(row):
|
|
return unit
|
|
names = []
|
|
for part in re.findall(r"\d+|[^\d]+", unit):
|
|
part = part.strip(" ,")
|
|
if not part:
|
|
continue
|
|
known = next((u["label"].split()[0] for u in VERIFIED.values() if u["code"] == part), None)
|
|
entry = workplaces.name_of(workplaces.TUKE, part) if part.isdigit() and not known else None
|
|
names.append(known or (f"{entry['name']} ({part})" if entry else f"pracovisko {part}" if part.isdigit() else part))
|
|
return ", ".join(names)
|