Compare commits

...
Author SHA1 Message Date
Tirsvad c2a8767fb0 Add README with setup, run, test and Doxygen instructions
Follow the Higher Lower README template: project description, local
.venv setup with pip upgrade, running the machine, tests and code
checks, source documentation, layout and license.

Closes #5
Task: MIL-001#5
2026-10-06 19:45:09 +08:00
Tirsvad 322efae5b4 Merge pull request 'MIL-001: project skeleton and tooling' (#19) from mil-001-project-setup into main
TirSystem/github-action: Sync GitHub mirror metadata / sync-metadata (push) Successful in 5s
Reviewed-on: Tirsvad-Udemy-100_days_of_code/015-coffee_machine#19
2026-10-04 18:31:21 +02:00
Tirsvad 572074ae73 Set up project skeleton and tooling for MIL-001
Add pyproject.toml (Python >=3.13, no runtime dependencies, pytest, ruff
and mypy as dev extras), a Doxyfile that scans src/, the
src/coffee_machine package with stub constants and main modules, and a
pytest smoke test. Ignore Doxygen output in .gitignore.

Closes #1
Closes #2
Closes #3
Closes #4
Refs #5

Task: MIL-001#1
Task: MIL-001#2
Task: MIL-001#3
Task: MIL-001#4
2026-10-05 00:30:18 +08:00
Tirsvad c3e225b049 Merge pull request 'Add planning baseline: BC, SA, PP and MIL-001 to MIL-003' (#18) from plan-baseline into main
TirSystem/github-action: Sync GitHub mirror metadata / sync-metadata (push) Successful in 6s
Reviewed-on: Tirsvad-Udemy-100_days_of_code/015-coffee_machine#18
2026-10-04 18:26:38 +02:00
9 changed files with 193 additions and 1 deletions
+3
View File
@@ -174,3 +174,6 @@ cython_debug/
# PyPI configuration file
.pypirc
# Doxygen output
docs/doxygen/
+14
View File
@@ -0,0 +1,14 @@
# Doxygen configuration for the coffee machine. Run: doxygen Doxyfile
PROJECT_NAME = "Coffee Machine"
PROJECT_BRIEF = "Day 15 of Udemy's 100 Days of Code Python bootcamp"
OUTPUT_DIRECTORY = docs/doxygen
INPUT = src
FILE_PATTERNS = *.py
RECURSIVE = YES
OPTIMIZE_OUTPUT_JAVA = YES
EXTRACT_ALL = YES
JAVADOC_AUTOBRIEF = YES
GENERATE_HTML = YES
GENERATE_LATEX = NO
QUIET = YES
WARN_IF_UNDOCUMENTED = YES
+101 -1
View File
@@ -1,2 +1,102 @@
# 015-coffee_machine
# Coffee Machine
A console game from Udemy's *100 Days of Code: The Complete Python Pro Bootcamp*
(day 15). A virtual coffee machine serves espresso, latte and cappuccino. Pay with
US coins (quarters, dimes, nickels and pennies). The machine checks its water, milk
and coffee before it serves, refunds you if you pay too little and gives change if
you pay too much.
```
What would you like? (espresso/latte/cappuccino): latte
Please insert coins.
How many quarters?: 10
How many dimes?: 0
How many nickels?: 0
How many pennies?: 0
Here is your latte. Enjoy!
```
- Python 3.13 or newer, no runtime dependencies.
- Type `report` to see the water, milk, coffee and money in the machine, and `off`
to switch the machine off.
- The function names follow the assignment: `is_resource_sufficient`,
`process_coins`, `is_transaction_successful`, `make_coffee`.
- Money is counted in whole cents inside the program, so change is never off by a
rounding error.
## Requirements
- [Python](https://www.python.org/downloads/) 3.13 or newer
- Optional: [Doxygen](https://www.doxygen.nl/) to build the source documentation
## Set up
Create a local virtual environment in `.venv`, activate it, and upgrade `pip`.
Windows (PowerShell):
```powershell
python -m venv .venv
.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip
```
Windows (Git Bash), Linux and macOS:
```bash
python -m venv .venv
source .venv/Scripts/activate # Linux/macOS: source .venv/bin/activate
python -m pip install --upgrade pip
```
The machine itself needs nothing more. To run the tests and the code checks, install
the development tools:
```bash
python -m pip install -e ".[dev]"
```
## Run the coffee machine
```bash
python -m coffee_machine
```
Type `espresso`, `latte` or `cappuccino` and press Enter, then enter the coins.
Type `report` for the machine's resources, or `off` to quit.
## Run the tests
```bash
python -m pytest
```
Check the code style and types:
```bash
python -m ruff check src tests
python -m ruff format --check src tests
python -m mypy src tests
```
## Build the source documentation
The source uses Doxygen comments. The HTML output goes to `docs/doxygen/html`.
```bash
doxygen Doxyfile
```
## Project layout
| Path | Content |
| --- | --- |
| `src/coffee_machine/` | The machine: `main.py` (the loop), `constants.py` (menu, coins, starting resources) |
| `tests/` | pytest tests |
| `docs/` | Planning and review documents (business case, plan, milestones) |
| `pyproject.toml` | Project configuration |
| `Doxyfile` | Doxygen configuration |
## License
GNU Affero General Public License v3.0. See [LICENSE](LICENSE).
+32
View File
@@ -0,0 +1,32 @@
[build-system]
requires = ["setuptools>=68"]
build-backend = "setuptools.build_meta"
[project]
name = "coffee-machine"
version = "0.1.0"
description = "Console coffee machine: Day 15 of Udemy's 100 Days of Code Python bootcamp."
readme = "README.md"
requires-python = ">=3.13"
license = { file = "LICENSE" }
dependencies = []
[project.optional-dependencies]
dev = ["pytest>=8", "ruff", "mypy"]
[project.scripts]
coffee-machine = "coffee_machine.main:main"
[tool.setuptools.packages.find]
where = ["src"]
[tool.pytest.ini_options]
testpaths = ["tests"]
pythonpath = ["src"]
[tool.ruff]
line-length = 88
[tool.mypy]
strict = true
mypy_path = "src"
+4
View File
@@ -0,0 +1,4 @@
"""!
@file __init__.py
@brief Console coffee machine package.
"""
+8
View File
@@ -0,0 +1,8 @@
"""!
@file __main__.py
@brief Allow `python -m coffee_machine`.
"""
from coffee_machine.main import main
main()
+6
View File
@@ -0,0 +1,6 @@
"""!
@file constants.py
@brief Constants for the coffee machine: menu, coins and starting resources.
The values are added in MIL-002 ("Define constants").
"""
+12
View File
@@ -0,0 +1,12 @@
"""!
@file main.py
@brief Entry point of the coffee machine.
"""
def main() -> None:
"""!
@brief Run the coffee machine.
The ordering loop is added in MIL-002 ("Implement main loop").
"""
+13
View File
@@ -0,0 +1,13 @@
"""!
@file test_smoke.py
@brief Smoke test that the package imports.
"""
from coffee_machine import main as main_module
def test_main_is_callable() -> None:
"""!
@brief The entry point runs without error.
"""
main_module.main()