vector-tompy 2024.8.14.10.43__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vector_tompy-2024.8.14.10.43/.gitignore +4 -0
- vector_tompy-2024.8.14.10.43/PKG-INFO +15 -0
- vector_tompy-2024.8.14.10.43/README.md +1 -0
- vector_tompy-2024.8.14.10.43/pyproject.toml +24 -0
- vector_tompy-2024.8.14.10.43/src/__init__.py +0 -0
- vector_tompy-2024.8.14.10.43/src/vector2.py +122 -0
- vector_tompy-2024.8.14.10.43/tests/test_vector2.py +67 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: vector-tompy
|
|
3
|
+
Version: 2024.8.14.10.43
|
|
4
|
+
Summary: Vectors for tompy projects
|
|
5
|
+
Author: tompy
|
|
6
|
+
Classifier: Development Status :: 3 - Alpha
|
|
7
|
+
Classifier: Intended Audience :: Developers
|
|
8
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
11
|
+
Requires-Python: >=3.9
|
|
12
|
+
Requires-Dist: sympy>=1.13.0
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
|
|
15
|
+
Vectors for tompy projects
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Vectors for tompy projects
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "vector-tompy"
|
|
7
|
+
description = "Vectors for tompy projects"
|
|
8
|
+
version = "2024.08.14.10.43"
|
|
9
|
+
requires-python = ">=3.9"
|
|
10
|
+
dependencies = ["sympy>=1.13.0"]
|
|
11
|
+
authors = [
|
|
12
|
+
{ name = "tompy" },
|
|
13
|
+
]
|
|
14
|
+
readme = "README.md"
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 3 - Alpha",
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"Programming Language :: Python :: 3.9",
|
|
19
|
+
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
|
|
20
|
+
"Operating System :: OS Independent",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
[tool.hatch.build.targets.wheel]
|
|
24
|
+
packages = ["src/vector_tompy"]
|
|
File without changes
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from decimal import Decimal
|
|
3
|
+
from math import sqrt
|
|
4
|
+
from typing import Self, Iterator
|
|
5
|
+
|
|
6
|
+
from math_tompy.symbolic import expr_to_calc
|
|
7
|
+
from sympy import Point2D
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@dataclass
|
|
11
|
+
class Vector2:
|
|
12
|
+
x: Decimal
|
|
13
|
+
y: Decimal
|
|
14
|
+
|
|
15
|
+
def __init__(self, x: Decimal, y: Decimal) -> None:
|
|
16
|
+
self.x = Decimal(x)
|
|
17
|
+
self.y = Decimal(y)
|
|
18
|
+
|
|
19
|
+
def __add__(self, other: Self) -> Self:
|
|
20
|
+
x_: Decimal = self.x + other.x
|
|
21
|
+
y_: Decimal = self.y + other.y
|
|
22
|
+
vector: Self = Vector2(x=x_, y=y_)
|
|
23
|
+
return vector
|
|
24
|
+
|
|
25
|
+
def __sub__(self, other: Self) -> Self:
|
|
26
|
+
x_: Decimal = self.x - other.x
|
|
27
|
+
y_: Decimal = self.y - other.y
|
|
28
|
+
vector: Self = Vector2(x=x_, y=y_)
|
|
29
|
+
return vector
|
|
30
|
+
|
|
31
|
+
def __mul__(self, other: Self | Decimal) -> Self:
|
|
32
|
+
if isinstance(other, Vector2):
|
|
33
|
+
x_: Decimal = self.x * other.x
|
|
34
|
+
y_: Decimal = self.y * other.y
|
|
35
|
+
elif isinstance(other, Decimal):
|
|
36
|
+
x_: Decimal = self.x * other
|
|
37
|
+
y_: Decimal = self.y * other
|
|
38
|
+
else:
|
|
39
|
+
raise TypeError(f"Type '{type(other)}' of other is not supported for '{type(Self)}' multiplication.")
|
|
40
|
+
vector: Self = Vector2(x=x_, y=y_)
|
|
41
|
+
return vector
|
|
42
|
+
|
|
43
|
+
def __abs__(self) -> Decimal:
|
|
44
|
+
origin = Vector2Injector.from_decimal(x=Decimal(0), y=Decimal(0))
|
|
45
|
+
distance = origin.distance(other=self)
|
|
46
|
+
return distance
|
|
47
|
+
|
|
48
|
+
def __iter__(self):
|
|
49
|
+
return iter([self.x, self.y])
|
|
50
|
+
|
|
51
|
+
def __len__(self) -> int:
|
|
52
|
+
return 2
|
|
53
|
+
|
|
54
|
+
def __getitem__(self, index: int | slice) -> Decimal:
|
|
55
|
+
if isinstance(index, int):
|
|
56
|
+
if int == 0:
|
|
57
|
+
value: Decimal = self.x
|
|
58
|
+
elif int == 1:
|
|
59
|
+
value: Decimal = self.y
|
|
60
|
+
else:
|
|
61
|
+
raise IndexError(f"Index '{index}' out of valid range [0, 1].")
|
|
62
|
+
elif isinstance(index, slice):
|
|
63
|
+
# if wraparound:
|
|
64
|
+
# value: Self = self._get_slice_with_wraparound(slice_=index)
|
|
65
|
+
# else:
|
|
66
|
+
# value: Self = self._get_slice(slice_=index)
|
|
67
|
+
raise ValueError(f"__getitem__ does not support slice.")
|
|
68
|
+
else:
|
|
69
|
+
raise ValueError(f"__getitem__ requires an integer or a slice, not a {type(index)}.")
|
|
70
|
+
return value
|
|
71
|
+
|
|
72
|
+
def __eq__(self, other: Self) -> bool:
|
|
73
|
+
equality: bool = False
|
|
74
|
+
same_type: bool = isinstance(other, type(self))
|
|
75
|
+
if same_type:
|
|
76
|
+
same_x: bool = self.x == other.x
|
|
77
|
+
same_y: bool = self.y == other.y
|
|
78
|
+
equality = same_x and same_y
|
|
79
|
+
return equality
|
|
80
|
+
|
|
81
|
+
def __hash__(self):
|
|
82
|
+
return hash(self.__repr__())
|
|
83
|
+
|
|
84
|
+
def __repr__(self) -> str:
|
|
85
|
+
return f"{type(self).__name__}({self.x}, {self.y})"
|
|
86
|
+
|
|
87
|
+
@property
|
|
88
|
+
def unit(self) -> Self:
|
|
89
|
+
length: Decimal = abs(self)
|
|
90
|
+
x_: Decimal = self.x / length
|
|
91
|
+
y_: Decimal = self.y / length
|
|
92
|
+
vector: Self = Vector2Injector.from_decimal(x=x_, y=y_)
|
|
93
|
+
return vector
|
|
94
|
+
|
|
95
|
+
def distance(self, other: Self) -> Decimal:
|
|
96
|
+
pair_squares: list[Decimal] = [Decimal((value0 - value1) ** 2) for value0, value1 in zip(self, other)]
|
|
97
|
+
square_sum: Decimal = Decimal(sum(pair_squares))
|
|
98
|
+
root_of_pair_square_sum: Decimal = Decimal(sqrt(square_sum))
|
|
99
|
+
return root_of_pair_square_sum
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class Vector2Injector:
|
|
103
|
+
@staticmethod
|
|
104
|
+
def from_point(point: Point2D) -> Vector2:
|
|
105
|
+
x: Decimal = Decimal(expr_to_calc(expression=point.x).result())
|
|
106
|
+
y: Decimal = Decimal(expr_to_calc(expression=point.y).result())
|
|
107
|
+
vector: Vector2 = Vector2(x=x, y=y)
|
|
108
|
+
return vector
|
|
109
|
+
|
|
110
|
+
@staticmethod
|
|
111
|
+
def from_decimal(x: Decimal, y: Decimal) -> Vector2:
|
|
112
|
+
vector: Vector2 = Vector2(x=x, y=y)
|
|
113
|
+
return vector
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def positions_from(samples_x: int, samples_y: int, resolution: Decimal) -> Iterator[Vector2]:
|
|
117
|
+
x_positions: list[Decimal] = [sample * resolution for sample in range(0, samples_x)]
|
|
118
|
+
y_positions: list[Decimal] = [sample * resolution for sample in range(0, samples_y)]
|
|
119
|
+
|
|
120
|
+
positions: Iterator[Vector2] = (Vector2Injector.from_decimal(x=x, y=y) for x in x_positions for y in y_positions)
|
|
121
|
+
|
|
122
|
+
return positions
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
from decimal import Decimal
|
|
2
|
+
|
|
3
|
+
from src.vector2 import Vector2, Vector2Injector, positions_from
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_positions_from_one_sample_one_resolution_success():
|
|
7
|
+
# Setup
|
|
8
|
+
samples_x0: int = 1
|
|
9
|
+
samples_y0: int = 1
|
|
10
|
+
resolution0: Decimal = Decimal(1)
|
|
11
|
+
|
|
12
|
+
vector0: Vector2 = Vector2Injector.from_decimal(x=Decimal(0), y=Decimal(0))
|
|
13
|
+
vectors0: list[Vector2] = [vector0]
|
|
14
|
+
|
|
15
|
+
# Execution
|
|
16
|
+
vectors1: list[Vector2] = list(positions_from(samples_x=samples_x0, samples_y=samples_y0, resolution=resolution0))
|
|
17
|
+
|
|
18
|
+
# Validation
|
|
19
|
+
assert vectors0 == vectors1
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def test_positions_from_four_sample_two_resolution_success():
|
|
23
|
+
# Setup
|
|
24
|
+
samples_x0: int = 2
|
|
25
|
+
samples_y0: int = 2
|
|
26
|
+
resolution0: Decimal = Decimal(2)
|
|
27
|
+
|
|
28
|
+
vector0: Vector2 = Vector2Injector.from_decimal(x=Decimal(0), y=Decimal(0))
|
|
29
|
+
vector1: Vector2 = Vector2Injector.from_decimal(x=Decimal(0), y=Decimal(2))
|
|
30
|
+
vector2: Vector2 = Vector2Injector.from_decimal(x=Decimal(2), y=Decimal(0))
|
|
31
|
+
vector3: Vector2 = Vector2Injector.from_decimal(x=Decimal(2), y=Decimal(2))
|
|
32
|
+
vectors0: list[Vector2] = [vector0, vector1, vector2, vector3]
|
|
33
|
+
|
|
34
|
+
# Execution
|
|
35
|
+
vectors1: list[Vector2] = list(positions_from(samples_x=samples_x0, samples_y=samples_y0, resolution=resolution0))
|
|
36
|
+
|
|
37
|
+
# Validation
|
|
38
|
+
assert vectors0 == vectors1
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def test_positions_from_three_and_four_sample_half_resolution_success():
|
|
42
|
+
# Setup
|
|
43
|
+
samples_x0: int = 3
|
|
44
|
+
samples_y0: int = 4
|
|
45
|
+
resolution0: Decimal = Decimal("0.5")
|
|
46
|
+
|
|
47
|
+
vector0: Vector2 = Vector2Injector.from_decimal(x=Decimal(0), y=Decimal(0))
|
|
48
|
+
vector1: Vector2 = Vector2Injector.from_decimal(x=Decimal(0), y=Decimal("0.5"))
|
|
49
|
+
vector2: Vector2 = Vector2Injector.from_decimal(x=Decimal(0), y=Decimal(1))
|
|
50
|
+
vector3: Vector2 = Vector2Injector.from_decimal(x=Decimal(0), y=Decimal("1.5"))
|
|
51
|
+
vector4: Vector2 = Vector2Injector.from_decimal(x=Decimal("0.5"), y=Decimal(0))
|
|
52
|
+
vector5: Vector2 = Vector2Injector.from_decimal(x=Decimal("0.5"), y=Decimal("0.5"))
|
|
53
|
+
vector6: Vector2 = Vector2Injector.from_decimal(x=Decimal("0.5"), y=Decimal(1))
|
|
54
|
+
vector7: Vector2 = Vector2Injector.from_decimal(x=Decimal("0.5"), y=Decimal("1.5"))
|
|
55
|
+
vector8: Vector2 = Vector2Injector.from_decimal(x=Decimal(1), y=Decimal(0))
|
|
56
|
+
vector9: Vector2 = Vector2Injector.from_decimal(x=Decimal(1), y=Decimal("0.5"))
|
|
57
|
+
vector10: Vector2 = Vector2Injector.from_decimal(x=Decimal(1), y=Decimal(1))
|
|
58
|
+
vector11: Vector2 = Vector2Injector.from_decimal(x=Decimal(1), y=Decimal("1.5"))
|
|
59
|
+
vectors0: list[Vector2] = [vector0, vector1, vector2, vector3,
|
|
60
|
+
vector4, vector5, vector6, vector7,
|
|
61
|
+
vector8, vector9, vector10, vector11]
|
|
62
|
+
|
|
63
|
+
# Execution
|
|
64
|
+
vectors1: list[Vector2] = list(positions_from(samples_x=samples_x0, samples_y=samples_y0, resolution=resolution0))
|
|
65
|
+
|
|
66
|
+
# Validation
|
|
67
|
+
assert vectors0 == vectors1
|