Files
025-squirrel/src/squirrel/cli.py
T
Tirsvad 7459711243 Implement census analysis: read, count, summarise, write and CLI
Closes #11
Closes #12
Closes #13
Closes #14
Closes #15

Task: MIL-002#4
Task: MIL-002#5
Task: MIL-002#6
Task: MIL-002#7
Task: MIL-002#8
2026-10-13 15:37:51 +08:00

68 lines
2.0 KiB
Python

##
# @file cli.py
# @brief Command line entry point: count the squirrels and write the summary.
"""Command line entry point: count the squirrels and write the summary."""
import argparse
import pathlib
import sys
from collections.abc import Sequence
from squirrel import census
from squirrel.constants import (
DEFAULT_INPUT_PATH,
DEFAULT_OUTPUT_PATH,
EXIT_INPUT_MISSING,
)
##
# @brief Build the argument parser of the command line.
# @return The parser with the optional `input` and `output` positionals.
def _build_parser() -> argparse.ArgumentParser:
"""Build the argument parser of the command line."""
parser = argparse.ArgumentParser(
prog="squirrel",
description="Count the census squirrels by primary fur colour.",
)
parser.add_argument(
"input",
nargs="?",
type=pathlib.Path,
default=DEFAULT_INPUT_PATH,
help="census CSV file (default: %(default)s)",
)
parser.add_argument(
"output",
nargs="?",
type=pathlib.Path,
default=DEFAULT_OUTPUT_PATH,
help="summary CSV file to write (default: %(default)s)",
)
return parser
##
# @brief Run the census analysis from the command line.
# @param argv Arguments without the program name; `sys.argv` is used when None.
# @return 0 on success, 2 when the census file does not exist.
def main(argv: Sequence[str] | None = None) -> int:
"""Run the census analysis from the command line."""
args = _build_parser().parse_args(argv)
input_path: pathlib.Path = args.input
output_path: pathlib.Path = args.output
if not input_path.is_file():
print(f"Census file not found: {input_path}", file=sys.stderr)
return EXIT_INPUT_MISSING
counts = census.count_by_fur_color(census.read_csv(input_path))
summary = census.build_summary(counts)
census.write_csv(summary, output_path)
# print is the intended output here: the counts are shown to the participant.
for color, count in summary:
print(f"{color}: {count}")
return 0