diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..616cf0f --- /dev/null +++ b/.env.example @@ -0,0 +1,4 @@ +# Copy to .env and fill in. Never commit .env. +GITEA_TOKEN= +GITHUB_PAT= +GITHUB_USER= diff --git a/.gitignore b/.gitignore index 36b13f1..ef1a1da 100644 --- a/.gitignore +++ b/.gitignore @@ -174,3 +174,6 @@ cython_debug/ # PyPI configuration file .pypirc + +# Doxygen output +docs/doxygen/ diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 0000000..c4684b8 --- /dev/null +++ b/Doxyfile @@ -0,0 +1,12 @@ +PROJECT_NAME = "Secret Auction" +PROJECT_BRIEF = "A blind auction command line program" +OUTPUT_DIRECTORY = docs/doxygen +INPUT = src README.md +FILE_PATTERNS = *.py *.md +RECURSIVE = YES +OPTIMIZE_OUTPUT_JAVA = YES +EXTRACT_ALL = YES +USE_MDFILE_AS_MAINPAGE = README.md +GENERATE_HTML = YES +GENERATE_LATEX = NO +QUIET = YES diff --git a/docs/plan.md b/docs/plan.md new file mode 100644 index 0000000..07a9845 --- /dev/null +++ b/docs/plan.md @@ -0,0 +1,41 @@ +# Plan: Secret Auction Program (Day 9) + +## Context + +Udemy 100 Days of Code blind-auction CLI. The repository uses a Python `.gitignore`, an AGPL `LICENSE` and a git-ignored `.env` (tokens, never printed or committed). Python 3.13 or newer is required. + +## Working method + +Work on ONE milestone at a time. Each milestone is one branch (`milestone/NN-name`) and one pull request. When a milestone is finished, stop, verify it and review before starting the next. Milestones and issues are also tracked on the Gitea repository (via API, token from `.env`). + +## Milestone 1 - Project scaffold and repo metadata (`milestone/01-scaffold`) + +- [x] Create `src/secret_auction/__init__.py`, `tests/`, `docs/` +- [x] `pyproject.toml`: `requires-python >=3.13`, src layout, no runtime deps, `dev` extra (`pytest`), pytest config, console script +- [x] `.env.example`; `.env` and `.venv/` ignored; add `docs/doxygen/` to `.gitignore` +- [x] `constants.py` +- [x] `Doxyfile` +- [x] Set repository description and topics (`python`, `udemy`, `100-days-of-code`, `blind-auction`, `beginner`) via API +- [x] Create milestones and issues on the host (milestones M1-M4, issues #1-#12) +- [x] Verify: create `.venv`, upgrade pip, `pip install -e ".[dev]"` +- [x] Save plan and milestones in `docs/plan.md` + +## Milestone 2 - Core auction logic and env loader (`milestone/02-core-logic`) + +- [ ] `auction.py` (Doxygen comments): `add_bid`, `find_winner` (uses `max(bids, key=bids.get)`, `ValueError` on empty) +- [ ] `env.py`: stdlib `.env` loader (no python-dotenv); does not override existing environment variables +- [ ] `tests/test_auction.py`, `tests/test_env.py` +- Verify: `pytest` passes + +## Milestone 3 - CLI program (`milestone/03-cli`) + +- [ ] `main.py`: prompt name and numeric bid (re-prompt on invalid), bids dict kept outside the loop, "other bidders? yes/no", clear screen with newlines between bidders, announce the winner +- [ ] `tests/test_main.py` with monkeypatched `input` +- Verify: `pytest`; scripted run `python -m secret_auction.main` with two bidders + +## Milestone 4 - Documentation (`milestone/04-docs`) + +- [ ] `README.md` from the template (Overview, Requirements, Setup incl. creating/activating `.venv` and `python -m pip install --upgrade pip`, Run, Tests, License AGPL, Links) +- [ ] `docs/flowchart.md` (Mermaid plus link to the diagrams.net chart) +- [ ] Generate Doxygen docs if `doxygen` is installed +- Verify: README commands work verbatim; `.env` stays untracked diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..a585a93 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,26 @@ +[build-system] +requires = ["setuptools>=68"] +build-backend = "setuptools.build_meta" + +[project] +name = "secret-auction" +version = "0.1.0" +description = "A beginner-friendly blind auction program (Udemy 100 Days of Code, Day 9)." +readme = "README.md" +requires-python = ">=3.13" +license = "AGPL-3.0-or-later" +license-files = ["LICENSE"] +dependencies = [] + +[project.optional-dependencies] +dev = ["pytest>=8"] + +[project.scripts] +secret-auction = "secret_auction.main:main" + +[tool.setuptools.packages.find] +where = ["src"] + +[tool.pytest.ini_options] +testpaths = ["tests"] +pythonpath = ["src"] diff --git a/src/secret_auction/__init__.py b/src/secret_auction/__init__.py new file mode 100644 index 0000000..954be24 --- /dev/null +++ b/src/secret_auction/__init__.py @@ -0,0 +1,5 @@ +"""! @file __init__.py +@brief Secret Auction package: a blind auction command line program. +""" + +__version__ = "0.1.0" diff --git a/src/secret_auction/constants.py b/src/secret_auction/constants.py new file mode 100644 index 0000000..f199f24 --- /dev/null +++ b/src/secret_auction/constants.py @@ -0,0 +1,39 @@ +"""! @file constants.py +@brief Constants used by the Secret Auction program. +""" + +## Number of blank lines printed to hide previous bidders' entries. +CLEAR_SCREEN_LINES = 100 + +## Answers accepted as "yes" when asking for more bidders. +YES_ANSWERS = ("yes", "y") + +## Answers accepted as "no" when asking for more bidders. +NO_ANSWERS = ("no", "n") + +## Path of the file holding environment variables (tokens). +ENV_FILE = ".env" + +## Name of the environment variable holding the Gitea token. +GITEA_TOKEN_ENV_VAR = "GITEA_TOKEN" + +## Prompt asking for the bidder's name. +PROMPT_NAME = "What is your name? " + +## Prompt asking for the bid amount. +PROMPT_BID = "What is your bid? $" + +## Prompt asking whether more bidders exist. +PROMPT_MORE_BIDDERS = "Are there any other bidders? Type 'yes' or 'no'. " + +## Message shown when the bid is not a valid number. +MSG_INVALID_BID = "Please enter a valid, non-negative number." + +## Message shown when the yes/no answer is not understood. +MSG_INVALID_ANSWER = "Please type 'yes' or 'no'." + +## Template for the winner announcement. +MSG_WINNER = "The winner is {name} with a bid of ${amount:.2f}." + +## Welcome banner. +MSG_WELCOME = "Welcome to the secret auction program." diff --git a/tests/.gitkeep b/tests/.gitkeep new file mode 100644 index 0000000..e69de29