#!/usr/bin/env python3 """A small CLI that prints a customizable greeting.""" import argparse import unittest from collections.abc import Sequence def build_parser() -> argparse.ArgumentParser: """Create the command-line argument parser.""" parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("name", nargs="?", default="World", help="name to greet") parser.add_argument("-n", "--count", type=int, default=1, help="number of greetings") parser.add_argument("--uppercase", action="store_true", help="use uppercase output") parser.add_argument("--test", action="store_true", help="run the built-in tests") return parser def make_greeting(name: str, uppercase: bool = False) -> str: """Return a greeting for the supplied name.""" greeting = f"Hello, {name}!" return greeting.upper() if uppercase else greeting class GreetingTests(unittest.TestCase): def test_default_greeting(self) -> None: self.assertEqual(make_greeting("Ada"), "Hello, Ada!") def test_uppercase_greeting(self) -> None: self.assertEqual(make_greeting("Ada", uppercase=True), "HELLO, ADA!") def main(argv: Sequence[str] | None = None) -> int: """Parse arguments and run the CLI.""" args = build_parser().parse_args(argv) if args.test: suite = unittest.defaultTestLoader.loadTestsFromTestCase(GreetingTests) return 0 if unittest.TextTestRunner().run(suite).wasSuccessful() else 1 if args.count < 1: build_parser().error("--count must be at least 1") greeting = make_greeting(args.name, args.uppercase) for _ in range(args.count): print(greeting) return 0 if __name__ == "__main__": raise SystemExit(main())