Skip to content

Repository files navigation

FizzBuzz

Prints Fizz, Buzz or FizzBuzz for each number you give it. Deliberately overengineered — see Design.

Requirements

  • mise — installs and pins every other tool.
  • Python 3.15, pinned in .python-version and fetched by uv.

Install

mise trust
mise install

mise install is the whole bootstrap: it installs the pinned tools, then syncs the dependencies from the lockfile and installs the git hooks, which run the formatters and the type checker before each commit. mise trust is needed once per clone, because mise refuses to read an untrusted config.

Usage

Pass one or more numbers. Each prints on its own line, in the order given.

just run 15
just run 17 21 547 4 3 15
17
Fizz
547
4
Fizz
FizzBuzz

Both divisors are options:

OptionDefaultMeaning
--fizz-divisor3Divisor that yields Fizz
--buzz-divisor5Divisor that yields Buzz
just run 9 --fizz-divisor 9

Two argument rules:

  • click parses a leading dash as an option, so a negative number needs the POSIX separator: just run -- -3 -15.
  • With no arguments it prompts for a number. With no terminal, it exits non-zero and names the argument to pass.

The command is installed as fizzbuzz, so uv run fizzbuzz 15 does the same as just run 15.

Development

RecipePurpose
just run <numbers>Run the CLI
just fixRun every autofixer
just checkRun every read-only gate, then the tests
just lintRun the read-only gate alone
just testRun the test suite
just setupInstall dependencies from the lockfile
just dev-setupInstall the git hooks
just upgradeRefresh the lockfile to the newest allowed versions

just fix fixes every finding just check reports that a tool can fix. If a fixable finding remains after just fix, then just fix is missing that tool.

Design

  • Markers combine.Marker is the free monoid over label parts, with UNMARKED as its identity. classify folds one marker per rule, so no conditional selects the result.
  • Rules are data. Adding a DivisorRule adds a divisor, and neither the types nor the control flow change.
  • The empty case is a value. A number matching no rule gets UNMARKED, the identity element, so no Signal | None appears anywhere.
  • Input errors are return values. The input boundary returns Result, sequenced with Result.do and unwrapped once at the CLI edge. bind and lash are unused: they type-check only under the returns mypy plugin, and this project uses ty.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages