81 lines
2.8 KiB
Python
81 lines
2.8 KiB
Python
#!/usr/bin/env python3
|
|
"""Record and summarize the controlled ten-application cohort."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
from pathlib import Path
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
TRACKER = ROOT / "job_scout" / "state" / "application_cohort.json"
|
|
FIT_CLASSES = ("core", "adjacent", "stretch")
|
|
CHANNELS = ("strong", "moderate", "weak")
|
|
|
|
|
|
def load() -> dict:
|
|
return json.loads(TRACKER.read_text(encoding="utf-8"))
|
|
|
|
|
|
def save(data: dict) -> None:
|
|
TRACKER.write_text(json.dumps(data, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
|
|
|
|
|
def summary(data: dict) -> None:
|
|
applications = data["applications"]
|
|
print(f"Cohort: {data['cohort_id']} ({len(applications)}/10 applications)")
|
|
for fit_class in FIT_CLASSES:
|
|
count = sum(item["fit_class"] == fit_class for item in applications)
|
|
target = data["target_mix"][fit_class]
|
|
print(f" {fit_class}: {count}/{target}")
|
|
for channel in CHANNELS:
|
|
count = sum(item["channel"] == channel for item in applications)
|
|
print(f" channel {channel}: {count}")
|
|
outcomes: dict[str, int] = {}
|
|
for item in applications:
|
|
outcome = item.get("outcome", "open")
|
|
outcomes[outcome] = outcomes.get(outcome, 0) + 1
|
|
print(" outcomes: " + ", ".join(f"{key}={value}" for key, value in sorted(outcomes.items())))
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser()
|
|
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
subparsers.add_parser("summary")
|
|
add = subparsers.add_parser("add")
|
|
add.add_argument("--company", required=True)
|
|
add.add_argument("--role", required=True)
|
|
add.add_argument("--date", required=True)
|
|
add.add_argument("--fit-class", choices=FIT_CLASSES, required=True)
|
|
add.add_argument("--evidence-fit", type=float, required=True)
|
|
add.add_argument("--channel", choices=CHANNELS, required=True)
|
|
add.add_argument("--hard-gate", choices=("pass", "fail"), required=True)
|
|
add.add_argument("--outcome", default="open")
|
|
|
|
args = parser.parse_args()
|
|
data = load()
|
|
if args.command == "add":
|
|
if len(data["applications"]) >= 10:
|
|
raise SystemExit("cohort already contains ten applications")
|
|
if args.hard_gate == "fail" and args.fit_class != "stretch":
|
|
raise SystemExit("a hard-gate failure must be recorded as stretch")
|
|
data["applications"].append(
|
|
{
|
|
"company": args.company,
|
|
"role": args.role,
|
|
"application_date": args.date,
|
|
"fit_class": args.fit_class,
|
|
"evidence_fit": args.evidence_fit,
|
|
"hard_gate": args.hard_gate,
|
|
"channel": args.channel,
|
|
"outcome": args.outcome,
|
|
}
|
|
)
|
|
save(data)
|
|
summary(data)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|