| 1 |
Packages, modules, functions, variables, classes and constants follow PEP 8 casing (snake_case, PascalCase, UPPER_SNAKE) |
Pass |
analysis, read_data, to_data_dict, to_temp_list, average_temp, max_temp, row_for_day, hottest_row, day_in_fahrenheit are snake_case. |
| 2 |
Names state purpose in the domain's language; no unexplained abbreviations, no single-letter names outside tiny scopes |
Pass |
Names are the lectures' (temp_list, average_temp, data, rows); celsius states the unit. |
| 3 |
Code is produced by the project's formatter and passes its linter with no unexplained suppressions |
Pass |
ruff check and ruff format --check exit 0. One suppression exists, # noqa: E402 in tests/test_analysis.py, and it is explained: the import must follow pytest.importorskip("pandas") so that the module is skipped when the extra is missing. |
| 4 |
Every function and method signature is type-annotated, including -> None |
Pass |
Every function is annotated, including the return types pandas.DataFrame, list[int], float and int; the tests are annotated -> None. |
| 5 |
No bare except:, no swallowed exceptions; specific exceptions are raised and the cause is kept (raise ... from) |
Pass |
day_in_fahrenheit raises a specific ValueError with the day and the row count when the day is not in the table exactly once; nothing is caught or swallowed. |
| 6 |
No mutable default arguments and no shadowed builtins |
Pass |
The only default is an immutable DATA_FILE; no builtin is shadowed. |
| 7 |
Files, locks and connections are managed with context managers |
N-A |
The module opens no file itself; pandas.read_csv opens and closes the file. |
| 8 |
Public modules, classes and functions have docstrings that say what, not how |
Pass |
Module docstring and Doxygen @brief, @param, @return (and @throws) on every function; doxygen Doxyfile exits 0 with no warnings. |
| 9 |
Logging uses logging, not print; no secrets or personal data in log output |
N-A |
The module neither logs nor prints. |
| 10 |
Classes and operations trace to the Design Class Diagram they implement; deviations are recorded |
Pass |
No Design Class Diagram exists (a learning project of this size, recorded in the open issues of PP-001); the functions trace to the lectures and to the tasks of MIL-003. |
| 11 |
Tests exist for new behaviour, are named for the behaviour, and do not depend on order or the network |
Pass |
tests/test_analysis.py has 13 tests named for behaviour, one for each Go/No-Go criterion of MIL-003 plus the empty result for an unknown day; none depends on order or the network; pytest reports 27 passed. |
| 12 |
Type checker runs in strict mode without errors; Any is justified in a comment |
Pass |
python -m mypy runs with strict = true: no issues in 8 source files. The one Any is dict[Hashable, Any] of to_data_dict, justified in a comment (the cell values of the table are heterogeneous) and given by the signature of DataFrame.to_dict. |
| 13 |
Dependencies are declared and pinned in the project's dependency file, none unused |
Pass |
pandas and pandas-stubs are declared in the pandas and dev extras with lower bounds and are used; dependencies = [] is unchanged and csv_reader still imports no pandas. |
| 14 |
Each piece of knowledge (a business rule, constant, format, validation or query) is defined in one place; code is merged only where it expresses the same knowledge, not where it merely looks alike |
Pass |
Column names and Fahrenheit factors come from constants.py; the maximum is stated once (max_temp, reused by hottest_row); the temperature list is stated once (to_temp_list, reused by average_temp). |
| 15 |
Imports point inward: business-rule modules import no framework, database, UI or delivery-mechanism code, and there are no import cycles |
Pass |
analysis imports pandas and weather.constants; no import cycle; csv_reader does not import analysis. |
| 16 |
SOLID holds: a class or module has one reason to change; new behaviour is added by extension, not by editing a type test in several places; subclasses honour the contract of their base; protocols are narrow; high-level code depends on protocols or abstract types and receives its implementations |
Pass |
Small functions with one reason to change each; no class hierarchy. |