make staff-tier category labels reflect the actual --senior-threshold/--support-threshold values

This commit is contained in:
Miloš Jovanović 2026-08-04 22:32:06 +00:00
parent a621b94512
commit efce6f3dec
2 changed files with 31 additions and 12 deletions

View file

@ -119,7 +119,7 @@ def _group_sort_key(key: tuple) -> tuple:
def process_file(path: Path, campus: str, year: int, writer: csv.writer,
senior_threshold: float, support_threshold: float,
senior_threshold: float, support_threshold: float, labels: dict,
agg: dict | None = None, group_dims: tuple = (),
top_earners: dict | None = None, top_n: int = 10,
tie_breaker: itertools.count | None = None,
@ -157,7 +157,7 @@ def process_file(path: Path, campus: str, year: int, writer: csv.writer,
)
writer.writerow([
year, campus, parsed["title"], category,
classifier.CATEGORY_LABELS[category],
labels[category],
round(parsed["gross_pay"], 2), round(parsed["regular_pay"], 2),
round(parsed["overtime_pay"], 2), round(parsed["other_pay"], 2),
parsed["first_name"], parsed["last_name"],
@ -180,7 +180,7 @@ def process_file(path: Path, campus: str, year: int, writer: csv.writer,
return count
def write_aggregate_csv(agg: dict, group_dims: tuple, outpath: Path) -> None:
def write_aggregate_csv(agg: dict, group_dims: tuple, labels: dict, outpath: Path) -> None:
"""Write one row per (group_dims..., category) with employee count,
total/mean/median gross pay."""
header = list(group_dims) + [
@ -196,14 +196,14 @@ def write_aggregate_csv(agg: dict, group_dims: tuple, outpath: Path) -> None:
values = agg[key]
total = sum(values)
writer.writerow([
*prefix, category, classifier.CATEGORY_LABELS[category],
*prefix, category, labels[category],
len(values), round(total, 2), round(total / len(values), 2),
round(statistics.median(values), 2),
])
log.info("Aggregate CSV -> %s", outpath)
def write_top_earners_csv(top_earners: dict, outpath: Path) -> None:
def write_top_earners_csv(top_earners: dict, labels: dict, outpath: Path) -> None:
"""Write the top-N earners per (group_dims..., category) key, ranked
highest gross_pay first within each group."""
header = ["category", "category_label", "rank", "year", "campus", "title",
@ -219,7 +219,7 @@ def write_top_earners_csv(top_earners: dict, outpath: Path) -> None:
for rank, (gross_pay, _, row) in enumerate(ranked, start=1):
year, campus, title, gross, regular, overtime, other, first, last = row
writer.writerow([
category, classifier.CATEGORY_LABELS[category], rank,
category, labels[category], rank,
year, campus, title, round(gross, 2), round(regular, 2),
round(overtime, 2), round(other, 2), first, last,
])
@ -232,7 +232,7 @@ def _money(v: float) -> str:
return f"${v:,.0f}"
def print_console_summary(console_stats: dict) -> None:
def print_console_summary(console_stats: dict, labels: dict) -> None:
"""Print one formatted category-by-category summary table per year,
keyed off (year, category) -> [gross_pay, ...] entries in console_stats."""
label_w, col_w = 34, 16
@ -255,7 +255,7 @@ def print_console_summary(console_stats: dict) -> None:
median = statistics.median(values) if values else 0.0
total_count += count
total_pay += total
label = classifier.CATEGORY_LABELS[category]
label = labels[category]
print(f"{label:<{label_w}}{count:>{col_w},}"
f"{_money(total):>{col_w}}{_money(median):>{col_w}}")
@ -331,6 +331,7 @@ def main():
else:
log.info("--skip-download set, classifying cached data only.")
labels = classifier.category_labels(args.senior_threshold, args.support_threshold)
group_dims = tuple(dim for dim in ("year", "campus") if dim in args.group_by)
agg = {} if args.aggregate_output else None
top_earners = {} if args.top_earners_output else None
@ -350,7 +351,7 @@ def main():
log.info("No data for %s %s, skipping.", campus, year)
continue
count = process_file(path, campus, year, writer,
args.senior_threshold, args.support_threshold,
args.senior_threshold, args.support_threshold, labels,
agg=agg, group_dims=group_dims,
top_earners=top_earners, top_n=args.top_n,
tie_breaker=tie_breaker,
@ -365,13 +366,13 @@ def main():
log.info("Total rows written: %d -> %s", total_rows, output_path)
if agg is not None:
write_aggregate_csv(agg, group_dims, Path(args.aggregate_output))
write_aggregate_csv(agg, group_dims, labels, Path(args.aggregate_output))
if top_earners is not None:
write_top_earners_csv(top_earners, Path(args.top_earners_output))
write_top_earners_csv(top_earners, labels, Path(args.top_earners_output))
if console_stats is not None:
print_console_summary(console_stats)
print_console_summary(console_stats, labels)
if __name__ == "__main__":