diff --git a/examples/pure-hatch/pyproject.toml b/examples/pure-hatch/pyproject.toml index f2198b1fc..b0c60cb9b 100644 --- a/examples/pure-hatch/pyproject.toml +++ b/examples/pure-hatch/pyproject.toml @@ -47,3 +47,6 @@ select = [ [tool.ruff.isort] known-first-party = ["examplePy"] + +[tool.pytest.ini_options] +pythonpath = "src" diff --git a/examples/pure-hatch/src/examplePy/__init__.py b/examples/pure-hatch/src/examplePy/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/examples/pure-hatch/tests/examplePy/data/temperatures_testdata.csv b/examples/pure-hatch/tests/examplePy/data/temperatures_testdata.csv new file mode 100644 index 000000000..54d42f27b --- /dev/null +++ b/examples/pure-hatch/tests/examplePy/data/temperatures_testdata.csv @@ -0,0 +1,493 @@ +Year,Month,Temperature +1980,1,53 +1980,2,59 +1980,3,39 +1980,4,75 +1980,5,51 +1980,6,87 +1980,7,60 +1980,8,28 +1980,9,47 +1980,10,100 +1980,11,59 +1980,12,54 +1981,1,43 +1981,2,92 +1981,3,25 +1981,4,94 +1981,5,52 +1981,6,50 +1981,7,35 +1981,8,78 +1981,9,42 +1981,10,99 +1981,11,26 +1981,12,59 +1982,1,69 +1982,2,7 +1982,3,48 +1982,4,30 +1982,5,72 +1982,6,50 +1982,7,62 +1982,8,51 +1982,9,8 +1982,10,87 +1982,11,66 +1982,12,46 +1983,1,18 +1983,2,29 +1983,3,7 +1983,4,37 +1983,5,11 +1983,6,33 +1983,7,69 +1983,8,21 +1983,9,2 +1983,10,10 +1983,11,1 +1983,12,22 +1984,1,53 +1984,2,19 +1984,3,19 +1984,4,88 +1984,5,16 +1984,6,31 +1984,7,25 +1984,8,1 +1984,9,87 +1984,10,7 +1984,11,3 +1984,12,20 +1985,1,5 +1985,2,77 +1985,3,2 +1985,4,22 +1985,5,98 +1985,6,90 +1985,7,24 +1985,8,96 +1985,9,71 +1985,10,25 +1985,11,60 +1985,12,11 +1986,1,43 +1986,2,73 +1986,3,90 +1986,4,86 +1986,5,57 +1986,6,18 +1986,7,62 +1986,8,43 +1986,9,60 +1986,10,51 +1986,11,62 +1986,12,83 +1987,1,14 +1987,2,18 +1987,3,7 +1987,4,73 +1987,5,22 +1987,6,66 +1987,7,14 +1987,8,61 +1987,9,92 +1987,10,68 +1987,11,20 +1987,12,46 +1988,1,48 +1988,2,47 +1988,3,36 +1988,4,61 +1988,5,73 +1988,6,81 +1988,7,70 +1988,8,46 +1988,9,41 +1988,10,27 +1988,11,53 +1988,12,89 +1989,1,87 +1989,2,63 +1989,3,21 +1989,4,86 +1989,5,19 +1989,6,37 +1989,7,82 +1989,8,47 +1989,9,32 +1989,10,41 +1989,11,28 +1989,12,76 +1990,1,67 +1990,2,45 +1990,3,34 +1990,4,2 +1990,5,69 +1990,6,90 +1990,7,70 +1990,8,38 +1990,9,86 +1990,10,79 +1990,11,48 +1990,12,95 +1991,1,48 +1991,2,63 +1991,3,66 +1991,4,99 +1991,5,19 +1991,6,6 +1991,7,47 +1991,8,52 +1991,9,42 +1991,10,9 +1991,11,67 +1991,12,28 +1992,1,43 +1992,2,100 +1992,3,74 +1992,4,73 +1992,5,27 +1992,6,3 +1992,7,37 +1992,8,91 +1992,9,92 +1992,10,96 +1992,11,57 +1992,12,27 +1993,1,41 +1993,2,60 +1993,3,55 +1993,4,56 +1993,5,67 +1993,6,56 +1993,7,35 +1993,8,95 +1993,9,90 +1993,10,75 +1993,11,65 +1993,12,45 +1994,1,52 +1994,2,15 +1994,3,15 +1994,4,24 +1994,5,80 +1994,6,59 +1994,7,2 +1994,8,46 +1994,9,25 +1994,10,7 +1994,11,7 +1994,12,20 +1995,1,47 +1995,2,7 +1995,3,78 +1995,4,3 +1995,5,98 +1995,6,51 +1995,7,31 +1995,8,41 +1995,9,98 +1995,10,14 +1995,11,95 +1995,12,19 +1996,1,41 +1996,2,72 +1996,3,56 +1996,4,54 +1996,5,51 +1996,6,74 +1996,7,96 +1996,8,10 +1996,9,85 +1996,10,60 +1996,11,11 +1996,12,5 +1997,1,89 +1997,2,20 +1997,3,60 +1997,4,90 +1997,5,60 +1997,6,10 +1997,7,82 +1997,8,27 +1997,9,87 +1997,10,40 +1997,11,87 +1997,12,49 +1998,1,14 +1998,2,4 +1998,3,95 +1998,4,54 +1998,5,45 +1998,6,87 +1998,7,42 +1998,8,79 +1998,9,91 +1998,10,51 +1998,11,26 +1998,12,94 +1999,1,24 +1999,2,96 +1999,3,68 +1999,4,35 +1999,5,20 +1999,6,34 +1999,7,16 +1999,8,19 +1999,9,29 +1999,10,72 +1999,11,45 +1999,12,14 +2000,1,1 +2000,2,77 +2000,3,22 +2000,4,56 +2000,5,95 +2000,6,1 +2000,7,82 +2000,8,73 +2000,9,5 +2000,10,51 +2000,11,70 +2000,12,17 +2001,1,67 +2001,2,0 +2001,3,75 +2001,4,23 +2001,5,24 +2001,6,94 +2001,7,79 +2001,8,55 +2001,9,15 +2001,10,53 +2001,11,39 +2001,12,57 +2002,1,38 +2002,2,65 +2002,3,70 +2002,4,16 +2002,5,87 +2002,6,38 +2002,7,4 +2002,8,37 +2002,9,61 +2002,10,2 +2002,11,96 +2002,12,71 +2003,1,70 +2003,2,95 +2003,3,72 +2003,4,53 +2003,5,9 +2003,6,29 +2003,7,87 +2003,8,0 +2003,9,99 +2003,10,12 +2003,11,53 +2003,12,0 +2004,1,81 +2004,2,17 +2004,3,91 +2004,4,90 +2004,5,95 +2004,6,15 +2004,7,90 +2004,8,45 +2004,9,97 +2004,10,67 +2004,11,9 +2004,12,96 +2005,1,93 +2005,2,65 +2005,3,80 +2005,4,77 +2005,5,61 +2005,6,98 +2005,7,9 +2005,8,58 +2005,9,79 +2005,10,55 +2005,11,51 +2005,12,97 +2006,1,4 +2006,2,71 +2006,3,7 +2006,4,17 +2006,5,76 +2006,6,76 +2006,7,44 +2006,8,77 +2006,9,45 +2006,10,90 +2006,11,5 +2006,12,44 +2007,1,48 +2007,2,89 +2007,3,31 +2007,4,53 +2007,5,11 +2007,6,29 +2007,7,58 +2007,8,10 +2007,9,80 +2007,10,53 +2007,11,19 +2007,12,57 +2008,1,0 +2008,2,57 +2008,3,83 +2008,4,23 +2008,5,11 +2008,6,81 +2008,7,7 +2008,8,59 +2008,9,77 +2008,10,72 +2008,11,62 +2008,12,86 +2009,1,71 +2009,2,35 +2009,3,40 +2009,4,69 +2009,5,75 +2009,6,59 +2009,7,24 +2009,8,27 +2009,9,71 +2009,10,56 +2009,11,22 +2009,12,65 +2010,1,52 +2010,2,63 +2010,3,34 +2010,4,35 +2010,5,38 +2010,6,10 +2010,7,40 +2010,8,65 +2010,9,50 +2010,10,43 +2010,11,93 +2010,12,32 +2011,1,90 +2011,2,65 +2011,3,23 +2011,4,94 +2011,5,23 +2011,6,26 +2011,7,57 +2011,8,67 +2011,9,85 +2011,10,69 +2011,11,93 +2011,12,59 +2012,1,9 +2012,2,85 +2012,3,94 +2012,4,7 +2012,5,77 +2012,6,13 +2012,7,10 +2012,8,47 +2012,9,17 +2012,10,56 +2012,11,87 +2012,12,79 +2013,1,59 +2013,2,41 +2013,3,51 +2013,4,81 +2013,5,90 +2013,6,32 +2013,7,87 +2013,8,63 +2013,9,46 +2013,10,84 +2013,11,17 +2013,12,77 +2014,1,100 +2014,2,35 +2014,3,83 +2014,4,27 +2014,5,89 +2014,6,27 +2014,7,34 +2014,8,20 +2014,9,58 +2014,10,11 +2014,11,70 +2014,12,42 +2015,1,81 +2015,2,21 +2015,3,52 +2015,4,51 +2015,5,12 +2015,6,46 +2015,7,13 +2015,8,46 +2015,9,13 +2015,10,73 +2015,11,98 +2015,12,83 +2016,1,33 +2016,2,68 +2016,3,89 +2016,4,55 +2016,5,81 +2016,6,81 +2016,7,91 +2016,8,33 +2016,9,10 +2016,10,73 +2016,11,96 +2016,12,12 +2017,1,41 +2017,2,74 +2017,3,20 +2017,4,64 +2017,5,56 +2017,6,56 +2017,7,21 +2017,8,15 +2017,9,79 +2017,10,12 +2017,11,20 +2017,12,4 +2018,1,82 +2018,2,90 +2018,3,47 +2018,4,53 +2018,5,99 +2018,6,23 +2018,7,84 +2018,8,18 +2018,9,90 +2018,10,11 +2018,11,31 +2018,12,96 +2019,1,40 +2019,2,5 +2019,3,21 +2019,4,92 +2019,5,73 +2019,6,51 +2019,7,11 +2019,8,22 +2019,9,8 +2019,10,74 +2019,11,52 +2019,12,54 +2020,1,29 +2020,2,87 +2020,3,46 +2020,4,81 +2020,5,27 +2020,6,87 +2020,7,72 +2020,8,46 +2020,9,30 +2020,10,47 +2020,11,49 +2020,12,70 diff --git a/examples/pure-hatch/tests/examplePy/test_temperature.py b/examples/pure-hatch/tests/examplePy/test_temperature.py new file mode 100644 index 000000000..d6f4cb561 --- /dev/null +++ b/examples/pure-hatch/tests/examplePy/test_temperature.py @@ -0,0 +1,59 @@ +"""Pytest-based unit test examples for the temperature module""" +import math + +from examplePy import temperature + + +def test_fahrenheit_to_celsius_positive(): + """Test F to C calculation for positive values""" + value = 95 + expected_result = 35 + result = temperature.fahrenheit_to_celsius(value) + + assert result == expected_result + + +def test_fahrenheit_to_celsius_negative(): + """Test F to C calculation for negative values""" + value = -13 + expected_result = -25 + result = temperature.fahrenheit_to_celsius(value) + + assert result == expected_result + + +def test_fahrenheit_to_celsius_zero(): + """Test F to C calculation for zero""" + value = 0 + expected_result = -17.7778 + result = temperature.fahrenheit_to_celsius(value) + + # Test that the result is close to the expected value, within tolerances + assert math.isclose(result, expected_result, abs_tol=0.0001) + + +def test_celsius_to_fahrenheit_positive(): + """Test C to F calculation for positive values""" + value = 100 + expected_result = 212 + result = temperature.celsius_to_fahrenheit(value) + + assert result == expected_result + + +def test_celsius_to_fahrenheit_negative(): + """Test C to F calculation for negative values""" + value = -20 + expected_result = -4 + result = temperature.celsius_to_fahrenheit(value) + + assert result == expected_result + + +def test_celsius_to_fahrenheit_zero(): + """Test C to F calculation for zero""" + value = 0 + expected_result = 32 + result = temperature.celsius_to_fahrenheit(value) + + assert result == expected_result diff --git a/examples/pure-hatch/tests/examplePy/test_temporal.py b/examples/pure-hatch/tests/examplePy/test_temporal.py new file mode 100644 index 000000000..85d069e4a --- /dev/null +++ b/examples/pure-hatch/tests/examplePy/test_temporal.py @@ -0,0 +1,44 @@ +"""Pytest-based unit test examples for the temporal module""" +import pathlib + +import numpy +import pandas +import pytest + +from examplePy import temperature, temporal + +# Get the path to the test data directory +TEST_DATA = pathlib.Path(__file__).parents[0] / "data" + + +@pytest.fixture +def temperatures(): + """Pytest fixture for temperature data, used to avoid duplicate code in all of our tests.""" + filename = TEST_DATA / "temperatures_testdata.csv" + df = pandas.read_csv(filename) + return df + + +def test_calc_annual_mean(temperatures): + """Test the calculation of the annual and total mean temperatures in the data""" + expected_mean_1988 = 13.3333 + expected_mean_final = 10.4347 + + # Calculate the means + df_mean, df_final = temporal.calc_annual_mean(temperatures) + + # Compare specific means to validate the calculations + assert numpy.isclose( + df_mean.loc[[1988], "Temperature"].iloc[0], expected_mean_1988) + assert numpy.isclose(df_final.loc["Temperature"], expected_mean_final) + + +def test_calc_annual_mean_no_data(): + """Negative test - test the calculation of the annual and total mean temperatures in the data when given no data results in an empty result""" + temperatures = pandas.DataFrame(columns=("Year", "Month", "Temperature")) + + # Calculate the means with no data + df_mean, df_final = temporal.calc_annual_mean(temperatures) + + # Verify the result dataframe is empty + assert df_mean.empty diff --git a/package-structure-code/code-style-linting-format.md b/package-structure-code/code-style-linting-format.md index 7e92c0eed..e41056658 100644 --- a/package-structure-code/code-style-linting-format.md +++ b/package-structure-code/code-style-linting-format.md @@ -214,6 +214,7 @@ Depending on your project, you might want to add the following to sort imports c :::{literalinclude} ../examples/pure-hatch/pyproject.toml :language: toml :start-at: [tool.ruff.isort] +:end-before: [tool.pytest.ini_options] ::: ## How to use code formatter in your local workflow diff --git a/package-structure-code/pyproject-toml-python-package-metadata.md b/package-structure-code/pyproject-toml-python-package-metadata.md index 46bdd09e7..08d9b5ada 100644 --- a/package-structure-code/pyproject-toml-python-package-metadata.md +++ b/package-structure-code/pyproject-toml-python-package-metadata.md @@ -195,6 +195,7 @@ Then specify dependency groups as follows: :::{literalinclude} ../examples/pure-hatch/pyproject.toml :language: toml :start-at: [project.optional-dependencies] +:end-before: [tool.ruff] ::: Following the above example, you install dependencies like this: