PYTHON WEBSITE CHECKER - PROGRAM CONSTRUCTION L01-L03

Fictional Harbour Office data. Original teaching examples.
Requires Python 3.10 or newer; standard library only; no network access.

1. Extract the companion ZIP. Copy this folder before experimenting.
2. Open this folder in your editor and its terminal.
3. Run python stage01_rule.py, then stage02_records.py (L01).
4. Run python stage03_files.py, then stage04_report.py (L02).
5. Run python stage05_links.py (L03).
Use python3 or py instead of python if that is your installed command.
Each stage is a complete executable version. Later stages use helper files
beside them. Keep the folder together; do not move a script by itself.

site/: four HTML input fixtures. Open in an editor to change input facts.
page_reader.py: turns saved HTML into page records.
report_tools.py: collects records, checks title/description rules, prints.
link_tools.py: checks local file targets and attaches findings by page name.
exercises/: deliberately unfinished functions. Replace NotImplementedError.
solutions/: separated explanations and complete independent solutions.
python test_checker.py: 16 checks, including default outputs and edge cases.

DEFAULT FINAL REPORT
contact.html | Duplicate title: services.html
index.html | Missing local target: missing-pricing.html
services.html | Missing description; Duplicate title: contact.html
untitled.html | Missing title
Pages checked: 4
Pages needing review: 4
Issues: 5

The report compares title text after surrounding-space cleaning and casefold.
It flags missing title/description, multiple or unclosed title elements,
duplicate title text and missing local file destinations. It also preserves
read-failure records. The supplied site has deliberate issues; do not expect
all green results.

LOCAL LINK CONVENTIONS
Relative paths start beside the source page. A beginning / means site root.
A trailing / means that folder's index.html. Query/fragment text is ignored
for file existence. Scheme/network destinations and fragment-only links are
excluded; no external requests occur. No JavaScript or live server routing
is executed. HTMLParser is not a complete HTML validator. A clean report
means no findings under these implemented checks, not complete SEO validity.

Run python solutions/L03_export.py to create solutions/checker_issues.csv.
The CSV contains one row per issue, not an inventory of every checked page.
