kiosk_vanilla / backend /tools /faculty_profile.py
Monish Vijay Kumar
Deploy Northwestern CS Kiosk Docker Space with checkpoint and inference runtime
7056be6
Raw
History Blame
2.96 kB
"""Helper functions for faculty record lookups used by multiple blueprints."""
from __future__ import annotations
import difflib
from typing import Any, Dict, List, Optional, Tuple
from ..data.utils import canonicalize_name, generate_name_variants
from .base import AnalysisContext
def _lookup_record(context: AnalysisContext, target_name: str) -> Tuple[Any, List[str], Optional[Dict[str, Any]]]:
"""Return the faculty record matching ``target_name`` and any lookup notes."""
notes: List[str] = []
dataset = context.catalog.get("faculty")
record = dataset.get_by_key(target_name)
if record is None:
target_canonical = canonicalize_name(target_name)
for row in dataset.records:
if canonicalize_name(row.get("Name", "")) == target_canonical:
record = row
break
if record is None:
candidates = [row.get("Name", "") for row in dataset.records if row.get("Name")]
closest = difflib.get_close_matches(target_name, candidates, n=1, cutoff=0.6)
if closest:
record = dataset.get_by_key(closest[0])
notes.append(f"Showing results for '{closest[0]}' (closest match).")
# Fallback: some names appear only in office-assignment CSVs (e.g., "Bain,Connor").
# Try to match those assignee names back into the faculty roster using
# common name permutations.
office_row: Optional[Dict[str, Any]] = None
if record is None:
offices = context.catalog.try_get("faculty_offices")
if offices:
for row in offices.records:
assignee = row.get("Assignee Name") or row.get("Assignee") or row.get("Name")
if not assignee:
continue
# If the assignee directly matches the target name (or its variants),
# prefer returning the matched faculty roster row when available; if
# no roster row matches, keep the office row as a fallback to emit
# office/location facts.
matched = False
for variant in generate_name_variants(assignee):
# If the variant matches the requested target, consider it a hit.
if canonicalize_name(variant) == canonicalize_name(target_name):
candidate = dataset.get_by_key(variant)
if candidate is not None:
record = candidate
notes.append(f"Matched '{assignee}' from faculty offices to roster entry '{candidate.get('Name')}'.")
matched = True
break
# remember office row as fallback if no roster entry exists
office_row = row
matched = True
break
if matched:
break
return record, notes, office_row