feat: implement core auction logic and env loader

- Add auction.py with add_bid and find_winner functions
- Add env.py with stdlib-based .env loader (no python-dotenv)
- Add tests/test_auction.py with test cases for auction functions
- Remove .env.example (tokens not meant to be committed)
- Update docs/plan.md to mark Milestone 2 as complete
This commit is contained in:
2026-10-04 14:03:22 +08:00
parent bcea547c8b
commit d2cf059337
5 changed files with 101 additions and 7 deletions
+27
View File
@@ -0,0 +1,27 @@
"""! @file auction.py
@brief Core blind auction logic (no input/output).
"""
def add_bid(bids: dict[str, float], name: str, amount: float) -> None:
"""! @brief Record a bid, replacing any earlier bid by the same bidder.
@param bids Dictionary mapping bidder name to bid amount (modified in place).
@param name Name of the bidder.
@param amount Bid amount; must not be negative.
@throws ValueError If the amount is negative.
"""
if amount < 0:
raise ValueError("Bid amount must not be negative.")
bids[name] = amount
def find_winner(bids: dict[str, float]) -> tuple[str, float]:
"""! @brief Find the highest bidder.
@param bids Dictionary mapping bidder name to bid amount.
@return Tuple of (winner name, winning amount). The first bidder wins ties.
@throws ValueError If there are no bids.
"""
if not bids:
raise ValueError("No bids have been placed.")
winner = max(bids, key=bids.__getitem__)
return winner, bids[winner]
+38
View File
@@ -0,0 +1,38 @@
"""! @file env.py
@brief Minimal `.env` file loader using only the standard library.
"""
import os
from pathlib import Path
def parse_env(text: str) -> dict[str, str]:
"""! @brief Parse `KEY=VALUE` lines.
@param text Contents of a `.env` file. Blank lines and `#` comments are ignored.
@return Dictionary of parsed variables; surrounding quotes are stripped.
"""
values: dict[str, str] = {}
for line in text.splitlines():
line = line.strip()
if not line or line.startswith("#") or "=" not in line:
continue
key, value = line.split("=", 1)
value = value.strip()
if len(value) >= 2 and value[0] == value[-1] and value[0] in "\"'":
value = value[1:-1]
values[key.strip()] = value
return values
def load_env(path: str | Path) -> dict[str, str]:
"""! @brief Load a `.env` file into `os.environ` without overriding existing variables.
@param path Path to the `.env` file; a missing file is not an error.
@return Dictionary of the variables read from the file.
"""
file = Path(path)
if not file.is_file():
return {}
values = parse_env(file.read_text(encoding="utf-8"))
for key, value in values.items():
os.environ.setdefault(key, value)
return values