Add constants.py and its test
Task: MIL-001#3
This commit is contained in:
@@ -0,0 +1,14 @@
|
|||||||
|
## @package weather
|
||||||
|
# @brief Reading CSV weather data, from Udemy's 100 Days of Code (day 25).
|
||||||
|
#
|
||||||
|
# @mainpage Weather Data
|
||||||
|
#
|
||||||
|
# The day-25 lectures read the weather data of one week from the file
|
||||||
|
# weather_data.csv: first with Python's built-in csv library, then with the
|
||||||
|
# pandas library, which makes the same work a one-liner. The package keeps the
|
||||||
|
# two ways side by side: csv_reader.py uses the standard library only, and
|
||||||
|
# analysis.py and export.py need the optional pandas extra.
|
||||||
|
#
|
||||||
|
# The constants of the package are in constants.py.
|
||||||
|
|
||||||
|
"""Reading CSV weather data, from Udemy's 100 Days of Code (day 25)."""
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
## @file constants.py
|
||||||
|
# @brief Constants of the weather data project.
|
||||||
|
#
|
||||||
|
# Every value that the day-25 lectures fix lives here, so that no other module
|
||||||
|
# contains a magic string or number: the name of the data file, the names of
|
||||||
|
# its columns, the factors of the Fahrenheit conversion and the name of the
|
||||||
|
# exported file.
|
||||||
|
|
||||||
|
"""Constants of the weather data project, as fixed by the day-25 lectures."""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Final
|
||||||
|
|
||||||
|
## @brief Folder of this package; the data file lies next to the modules.
|
||||||
|
PACKAGE_DIR: Final[Path] = Path(__file__).resolve().parent
|
||||||
|
|
||||||
|
## @brief Name of the weather data file of the lecture.
|
||||||
|
DATA_FILE_NAME: Final[str] = "weather_data.csv"
|
||||||
|
|
||||||
|
## @brief Full path of the weather data file, independent of the working folder.
|
||||||
|
DATA_FILE: Final[Path] = PACKAGE_DIR / DATA_FILE_NAME
|
||||||
|
|
||||||
|
## @brief Name of the file that the exported table is written to by default.
|
||||||
|
EXPORT_FILE_NAME: Final[str] = "new_data.csv"
|
||||||
|
|
||||||
|
## @brief Encoding of the CSV files that are read and written.
|
||||||
|
FILE_ENCODING: Final[str] = "utf-8"
|
||||||
|
|
||||||
|
## @brief Name of the column that holds the day of the week.
|
||||||
|
COLUMN_DAY: Final[str] = "day"
|
||||||
|
|
||||||
|
## @brief Name of the column that holds the temperature in degrees Celsius.
|
||||||
|
COLUMN_TEMP: Final[str] = "temp"
|
||||||
|
|
||||||
|
## @brief Name of the column that holds the weather condition, such as `Sunny`.
|
||||||
|
COLUMN_CONDITION: Final[str] = "condition"
|
||||||
|
|
||||||
|
## @brief Position of the temperature in a row that `csv.reader` returns.
|
||||||
|
TEMP_COLUMN_INDEX: Final[int] = 1
|
||||||
|
|
||||||
|
## @brief Numerator of the Celsius to Fahrenheit factor: `temp * 9 / 5 + 32`.
|
||||||
|
FAHRENHEIT_NUMERATOR: Final[int] = 9
|
||||||
|
|
||||||
|
## @brief Denominator of the Celsius to Fahrenheit factor: `temp * 9 / 5 + 32`.
|
||||||
|
FAHRENHEIT_DENOMINATOR: Final[int] = 5
|
||||||
|
|
||||||
|
## @brief Offset of the Celsius to Fahrenheit conversion: `temp * 9 / 5 + 32`.
|
||||||
|
FAHRENHEIT_OFFSET: Final[int] = 32
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
"""Shared pytest configuration for the weather data tests."""
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def isolated_working_directory(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
|
"""Run every test in an empty temporary working directory.
|
||||||
|
|
||||||
|
The export has a default file name relative to the working directory. Without
|
||||||
|
this fixture, a test that uses the default would write into the folder pytest
|
||||||
|
was started from.
|
||||||
|
"""
|
||||||
|
monkeypatch.chdir(tmp_path)
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
"""Tests of the constants that the day-25 lectures fix."""
|
||||||
|
|
||||||
|
from weather import constants
|
||||||
|
|
||||||
|
|
||||||
|
def test_data_file_is_the_one_of_the_lecture() -> None:
|
||||||
|
assert constants.DATA_FILE_NAME == "weather_data.csv"
|
||||||
|
|
||||||
|
|
||||||
|
def test_data_file_lies_next_to_the_modules_not_in_the_working_folder() -> None:
|
||||||
|
assert constants.DATA_FILE.is_absolute()
|
||||||
|
assert constants.DATA_FILE.parent == constants.PACKAGE_DIR
|
||||||
|
assert constants.DATA_FILE.name == constants.DATA_FILE_NAME
|
||||||
|
|
||||||
|
|
||||||
|
def test_column_names_match_the_header_of_the_lecture() -> None:
|
||||||
|
assert constants.COLUMN_DAY == "day"
|
||||||
|
assert constants.COLUMN_TEMP == "temp"
|
||||||
|
assert constants.COLUMN_CONDITION == "condition"
|
||||||
|
|
||||||
|
|
||||||
|
def test_temperature_is_the_second_value_of_a_row() -> None:
|
||||||
|
assert constants.TEMP_COLUMN_INDEX == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_fahrenheit_factors_give_the_lecture_formula() -> None:
|
||||||
|
celsius = 100
|
||||||
|
fahrenheit = (
|
||||||
|
celsius * constants.FAHRENHEIT_NUMERATOR / constants.FAHRENHEIT_DENOMINATOR
|
||||||
|
+ constants.FAHRENHEIT_OFFSET
|
||||||
|
)
|
||||||
|
assert fahrenheit == 212
|
||||||
|
|
||||||
|
|
||||||
|
def test_exported_file_has_the_name_of_the_lecture() -> None:
|
||||||
|
assert constants.EXPORT_FILE_NAME == "new_data.csv"
|
||||||
Reference in New Issue
Block a user