From 83ea047c6003305571f9984585eadbd9b0749a92 Mon Sep 17 00:00:00 2001 From: Rico Date: Wed, 14 Jan 2026 16:06:01 +0100 Subject: [PATCH 1/7] feat: solve task 2 --- .gitignore | 1 + diffusion2d.py | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..21d0b89 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.venv/ diff --git a/diffusion2d.py b/diffusion2d.py index 51a07f2..2278bae 100644 --- a/diffusion2d.py +++ b/diffusion2d.py @@ -38,6 +38,10 @@ def __init__(self): self.dt = None def initialize_domain(self, w=10., h=10., dx=0.1, dy=0.1): + assert isinstance(w, float) + assert isinstance(h, float) + assert isinstance(dx, float) + assert isinstance(dy, float) self.w = w self.h = h self.dx = dx @@ -45,7 +49,10 @@ def initialize_domain(self, w=10., h=10., dx=0.1, dy=0.1): self.nx = int(w / dx) self.ny = int(h / dy) - def initialize_physical_parameters(self, d=4., T_cold=300, T_hot=700): + def initialize_physical_parameters(self, d=4., T_cold=300., T_hot=700.): + assert isinstance(d, float) + assert isinstance(T_cold, float) + assert isinstance(T_hot, float) self.D = d self.T_cold = T_cold self.T_hot = T_hot From dd54c88a81f1441dc58d25bc5d6de3fe841e0758 Mon Sep 17 00:00:00 2001 From: Rico Date: Wed, 14 Jan 2026 16:52:03 +0100 Subject: [PATCH 2/7] feat: solve task 3 --- tests/unit/test_diffusion2d_functions.py | 58 ++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/tests/unit/test_diffusion2d_functions.py b/tests/unit/test_diffusion2d_functions.py index c4277ff..1522f77 100644 --- a/tests/unit/test_diffusion2d_functions.py +++ b/tests/unit/test_diffusion2d_functions.py @@ -2,6 +2,9 @@ Tests for functions in class SolveDiffusion2D """ +import numpy +import pytest + from diffusion2d import SolveDiffusion2D @@ -10,6 +13,9 @@ def test_initialize_domain(): Check function SolveDiffusion2D.initialize_domain """ solver = SolveDiffusion2D() + solver.initialize_domain(w=20.0, h=20.0, dx=0.5, dy=0.5) + assert solver.nx == 40 + assert solver.ny == 40 def test_initialize_physical_parameters(): @@ -17,6 +23,10 @@ def test_initialize_physical_parameters(): Checks function SolveDiffusion2D.initialize_domain """ solver = SolveDiffusion2D() + solver.dx = 0.5 + solver.dy = 0.5 + solver.initialize_physical_parameters(d=3.0, T_cold=200.0, T_hot=800.0) + assert solver.dt == pytest.approx(0.02083333333, rel=1e-6) def test_set_initial_condition(): @@ -24,3 +34,51 @@ def test_set_initial_condition(): Checks function SolveDiffusion2D.get_initial_function """ solver = SolveDiffusion2D() + solver.nx = 5 + solver.ny = 5 + solver.dx = 3 + solver.dy = 3 + solver.T_cold = 200.0 + solver.T_hot = 800.0 + + expected_result = numpy.array( + [ + [ + 200.0, + 200.0, + 200.0, + 200.0, + 200.0, + ], + [ + 200.0, + 200.0, + 200.0, + 200.0, + 200.0, + ], + [ + 200.0, + 200.0, + 800.0, + 200.0, + 200.0, + ], + [ + 200.0, + 200.0, + 200.0, + 200.0, + 200.0, + ], + [ + 200.0, + 200.0, + 200.0, + 200.0, + 200.0, + ], + ] + ) + + assert numpy.array_equal(solver.set_initial_condition(), expected_result) From 0199fb4c675196037e853973602936a27ec76c65 Mon Sep 17 00:00:00 2001 From: Rico Date: Wed, 14 Jan 2026 16:53:18 +0100 Subject: [PATCH 3/7] chore: add non-source files to gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 21d0b89..d9739ac 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ .venv/ +__pycache__/ +*.ipynb From be0322a47e8c47324f1128e515d5d683232208b4 Mon Sep 17 00:00:00 2001 From: Rico Date: Wed, 14 Jan 2026 16:57:54 +0100 Subject: [PATCH 4/7] refactor: task 3 understandability --- tests/unit/test_diffusion2d_functions.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/unit/test_diffusion2d_functions.py b/tests/unit/test_diffusion2d_functions.py index 1522f77..bd74863 100644 --- a/tests/unit/test_diffusion2d_functions.py +++ b/tests/unit/test_diffusion2d_functions.py @@ -41,6 +41,7 @@ def test_set_initial_condition(): solver.T_cold = 200.0 solver.T_hot = 800.0 + actual_result = solver.set_initial_condition() expected_result = numpy.array( [ [ @@ -81,4 +82,4 @@ def test_set_initial_condition(): ] ) - assert numpy.array_equal(solver.set_initial_condition(), expected_result) + assert numpy.array_equal(actual_result, expected_result) From be46d5d382b190dd785ee09aee8bace9e592e047 Mon Sep 17 00:00:00 2001 From: Rico Date: Wed, 14 Jan 2026 17:38:54 +0100 Subject: [PATCH 5/7] feat: solve task 4 --- tests/integration/test_diffusion2d.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/integration/test_diffusion2d.py b/tests/integration/test_diffusion2d.py index fd026b4..1cff2fd 100644 --- a/tests/integration/test_diffusion2d.py +++ b/tests/integration/test_diffusion2d.py @@ -2,6 +2,9 @@ Tests for functionality checks in class SolveDiffusion2D """ +import numpy +import pytest + from diffusion2d import SolveDiffusion2D @@ -10,6 +13,9 @@ def test_initialize_physical_parameters(): Checks function SolveDiffusion2D.initialize_domain """ solver = SolveDiffusion2D() + solver.initialize_domain(w=20.0, h=20.0, dx=5.0, dy=5.0) + solver.initialize_physical_parameters(d=5.0, T_cold=400.0, T_hot=600.0) + assert solver.dt == pytest.approx(1.25, rel=1e-6) def test_set_initial_condition(): @@ -17,3 +23,15 @@ def test_set_initial_condition(): Checks function SolveDiffusion2D.get_initial_function """ solver = SolveDiffusion2D() + solver.initialize_domain(w=20.0, h=20.0, dx=2.0, dy=2.0) + solver.initialize_physical_parameters(d=5.0, T_cold=400.0, T_hot=600.0) + actual_result = solver.set_initial_condition() + + expected_result = 400.0 * numpy.ones((10, 10)) + for i in range(10): + for j in range(10): + p2 = (i * 2.0 - 5.0) ** 2 + (j * 2.0 - 5.0) ** 2 + if p2 < 4: + expected_result[i, j] = 600.0 + + assert numpy.allclose(actual_result, expected_result) From edc5fcb7524a93c5fbda2a4da4f7807947172920 Mon Sep 17 00:00:00 2001 From: Rico Date: Wed, 14 Jan 2026 17:48:55 +0100 Subject: [PATCH 6/7] feat: solve task 5 --- coverage-report.pdf | Bin 0 -> 41016 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 coverage-report.pdf diff --git a/coverage-report.pdf b/coverage-report.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8d3f6c4c1bb294a09c636735ef391940f4d1f511 GIT binary patch literal 41016 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 Qz|0PSCM6Y;7KZ+R0D)0>$N&HU literal 0 HcmV?d00001 From c2767270b81b9f3557370eb9c296d971bc148583 Mon Sep 17 00:00:00 2001 From: Rico Date: Wed, 21 Jan 2026 02:20:06 +0100 Subject: [PATCH 7/7] feat: solve task 6 --- requirements.txt | 15 +++++++++++++++ tox.toml | 7 +++++++ 2 files changed, 22 insertions(+) create mode 100644 requirements.txt create mode 100644 tox.toml diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..a850b08 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,15 @@ +contourpy==1.3.3 +cycler==0.12.1 +fonttools==4.61.1 +iniconfig==2.3.0 +kiwisolver==1.4.9 +matplotlib==3.10.8 +numpy==2.4.1 +packaging==25.0 +pillow==12.1.0 +pluggy==1.6.0 +Pygments==2.19.2 +pyparsing==3.3.1 +pytest==9.0.2 +python-dateutil==2.9.0.post0 +six==1.17.0 diff --git a/tox.toml b/tox.toml new file mode 100644 index 0000000..3e2a990 --- /dev/null +++ b/tox.toml @@ -0,0 +1,7 @@ +requires = ["tox>=4"] +env_list = ["pytest_testing"] + +[env.pytest_testing] +description = "Run pytest" +deps = ["-r requirements.txt"] +commands = [["python", "-m", "pytest"]]