From 293e1df8b9c57ce48999333e9224f80c5ddb0179 Mon Sep 17 00:00:00 2001 From: Daniel Weschke Date: Mon, 12 Jan 2026 22:06:40 +0100 Subject: [PATCH] fix vertex --- src/fvr/geom2d.py | 16 ++++++++++----- src/fvr/typing.py | 3 +-- tests/test_geom2d.py | 22 +++++++++++++++++++++ tests/test_structure.py | 43 ++++++++++++++++------------------------- 4 files changed, 51 insertions(+), 33 deletions(-) create mode 100644 tests/test_geom2d.py diff --git a/src/fvr/geom2d.py b/src/fvr/geom2d.py index 2c3380b..7534b3d 100644 --- a/src/fvr/geom2d.py +++ b/src/fvr/geom2d.py @@ -5,8 +5,9 @@ from fvr.typing import FloatArray class Vertex(np.ndarray): """Point in 2d space using homogeneous coordinates.""" - def __init__(cls, x=0, y=0): + def __new__(cls, x=0, y=0): obj = np.asarray([x, y, 1]).view(cls) + return obj @property def x(self): @@ -16,12 +17,16 @@ class Vertex(np.ndarray): def y(self): return self[1] + @property + def w(self): + return self[2] + class Polygon: r"""Properties of a simple polygon. """ - def __init__(self, vertices: FloatArray|str): + def __init__(self, vertices: FloatArray | str): r""" Args: vertices: List of points, pair of x and y: ``[[x1, y1], [x2, y2], ...]`` @@ -31,19 +36,20 @@ class Polygon: self.vertices = vertices @staticmethod - def str2arr(vertices: str) -> list: + def str2arr(vertices: str) -> FloatArray: strm = re.match(r'\[.*\]', ''.join(vertices)) if strm and strm.group(): return eval(strm.group()) + return np.array([]) @property def area(self) -> float: r"""Determine the area of a simple polygon. Example: - >>> polygon([[0, 0], [0, 1], [1, 1], [1, 0]]).area + >>> Polygon([[0, 0], [0, 1], [1, 1], [1, 0]]).area 1.0 - >>> polygon('[[0, 0], [0, 1], [1, 1], [1, 0]]').area + >>> Polygon('[[0, 0], [0, 1], [1, 1], [1, 0]]').area 1.0 Shoelace formula, Gauss's area formula, surveyor's formula diff --git a/src/fvr/typing.py b/src/fvr/typing.py index 1cad337..d5663e7 100644 --- a/src/fvr/typing.py +++ b/src/fvr/typing.py @@ -1,4 +1,3 @@ -from collections.abc import Sequence import numpy.typing -type FloatArray = Sequence[float] | numpy.typing.NDArray[numpy.float64] +type FloatArray = numpy.typing.NDArray[numpy.float64] diff --git a/tests/test_geom2d.py b/tests/test_geom2d.py new file mode 100644 index 0000000..9333044 --- /dev/null +++ b/tests/test_geom2d.py @@ -0,0 +1,22 @@ +"""Test of geom2d module. + +""" +import numpy as np +import fvr.geom2d + +def test_vertex_obj(): + np.testing.assert_equal( + fvr.geom2d.Vertex(1, 2), np.array([1, 2, 1]), + 'incorrect object after creation') + +def test_vertex_x(): + np.testing.assert_equal( + fvr.geom2d.Vertex(1, 2).x, 1, 'incorrect x after creation') + +def test_vertex_y(): + np.testing.assert_equal( + fvr.geom2d.Vertex(1, 2).y, 2, 'incorrect y after creation') + +def test_vertex_w(): + np.testing.assert_equal( + fvr.geom2d.Vertex(1, 2).w, 1, 'incorrect w after creation') diff --git a/tests/test_structure.py b/tests/test_structure.py index b216ce3..629b538 100644 --- a/tests/test_structure.py +++ b/tests/test_structure.py @@ -1,53 +1,44 @@ """Test of structure module. """ -import unittest +import pytest import fvr.structure -class TestStructureBeam(unittest.TestCase): - def setUp(self): +class TestBeam: + @pytest.fixture(autouse=True) + def obj(self): self.obj = fvr.structure.Beam(1, 2, 3, 4, 5) - def test_volume(self): - self.assertEqual(self.obj.V, 12, 'incorrect volume after creation') + def test_beam_volume(self): + assert self.obj.V == 12 def test_volume_a(self): self.obj.A = 6 - self.assertEqual(self.obj.V, 24, 'incorrect volume after changing A') + assert self.obj.V == 24 def test_volume_l(self): self.obj.L = 7 - self.assertEqual(self.obj.V, 21, 'incorrect volume after changing L') + assert self.obj.V == 21 def test_mu(self): - self.assertEqual(self.obj.mu, 15, 'incorrect specific mass after creation') + assert self.obj.mu == 15 def test_m(self): - self.assertEqual(self.obj.m, 60, 'incorrect mass after creation') + assert self.obj.m == 60 def test_eigenfrequency(self): - self.assertEqual( - self.obj.eigenfrequency(1), 0.012770856732837836, - 'incorrect eigen-frequency after creation') + assert self.obj.eigenfrequency(1) == 0.012770856732837836 -class TestStructureTubeBuckling(unittest.TestCase): - def setUp(self): +class TestTubeBuckling: + @pytest.fixture(autouse=True) + def obj(self): self.obj = fvr.structure.TubeBuckling(1, 0.2, 3, h=4) def test_force(self): - self.assertEqual( - self.obj.force(), 1.8518518518518516, - 'incorrect buckling force after creation') + assert self.obj.force() == 1.8518518518518516 def test_pressure(self): - self.assertEqual( - self.obj.pressure(), 0.6172839506172838, - 'incorrect buckling force after creation') + assert self.obj.pressure() == 0.6172839506172838 def test_stress(self): - self.assertEqual( - self.obj.stress(), 0.46296296296296297, - 'incorrect buckling force after creation') - -if __name__ == '__main__': - unittest.main() + assert self.obj.stress() == 0.46296296296296297