Код: Выделить всё
import copy
import math
class vector2d:
#class variables
#builders
def __init__(self):
"""
Empty vector
"""
self.components : dict[str:float] = {}
self.components["x"] = 0
self.components["y"] = 0
def from_x_y(self, x : float = 0, y : float = 0):
"""
Vector declared using x and y components
"""
self.components["x"] = x
self.components["y"] = y
return self
def from_module_angle(self, module : float = 0 , angle : float = 0):
"""
Vector declared using module and angle
"""
self.components["x"] = module * math.cos(angle)
self.components["y"] = module * math.sin(angle)
return self
#copy
def __copy__(self, memodict={}):
return vector2d().from_x_y(self.get_x(), self.get_y())
def __deepcopy__(self, memodict={}):
return vector2d().from_x_y(self.get_x(), self.get_y())
#getters
#components
def get_component(self, key : str) -> float:
"""
Returns a component
"""
return self.components[key]
def get_components(self,*keys : str) -> tuple[float]:
"""
Returns the value of the components of the vector\n
Uses the name of each component as the parameter
Slow
"""
components_list : list[float] = []
for key in keys:
components_list.append(self.components[key])
return tuple(components_list)
def get_x(self) -> float:
"""
return the x component
"""
return self.components["x"]
def get_y(self) -> float:
"""
return the y component
"""
return self.components["y"]
#module
def get_module(self) -> float:
"""
Returns the module of the vector, works for any n dimension vector
"""
module = math.sqrt(sum(map(lambda i: i * i, self.components.values())))
return module
#get angle
def get_angle_2d(self) -> float:
"""
Returns the angle of a 2d vector
"""
#atan2 is already robust against division by zero
angle = math.atan2(self.components["y"],self.components["x"])
return angle
#setters
#components
def set_components(self,*keys_values : tuple[str | float]):
"""
Sets the components of the vector
## parameters
### keys_values : tuple
first value is the key of a component\n
second value is the value of the component
"""
for x,y in keys_values:
if x not in self.components.keys():
raise ValueError(f"{x} is not a component in the vector")
if not isinstance(y,float) and not isinstance(y,int):
raise ValueError(f"{y} should be type float or int not {type(y)}")
self.components[x] = y
#module and angle
def set_module_angle(self, module : float = 0 , angle : float = 0):
"""
Set module and angle of a vector
"""
self.components["x"] = module * math.cos(angle)
self.components["y"] = module * math.sin(angle)
return self
#set to zero
def clear_vector(self):
"""
sets all the components to zero
"""
self.components["x"] = 0
self.components["y"] = 0
#vectors operations
def vector_addition(self, vector : 'vector2d'):
"""
Returns the sum of the two vectors
"""
add_vector : vector2d = vector2d()
add_vector.components["x"] = self.components["x"] + vector.components["x"]
add_vector.components["y"] = self.components["y"] + vector.components["y"]
return add_vector
def scalar_multiplication(self, multiplier : float):
"""
Returns the vector multiplied by a scalar value
"""
multiply_vector : vector2d = vector2d()
multiply_vector.components["x"] = self.components["x"] * multiplier
multiply_vector.components["y"] = self.components["y"] * multiplier
return multiply_vector
Код: Выделить всё
import cProfile
from simpy_starlinetor.physics_starlinetor.vectors import *
vector_1 : vector2d = vector2d().from_x_y(10,10)
vector_2 : vector2d = vector2d().from_x_y(20,20)
def test(vector_1, vector_2):
for i in range(100000):
vector_1.vector_addition(vector_2)
cProfile.run("test(vector_1, vector_2)")
Код: Выделить всё
200004 function calls in 0.135 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.135 0.135 :1()
1 0.034 0.034 0.135 0.135 test.py:10(test)
100000 0.075 0.000 0.101 0.000 vectors.py:123(vector_addition)
100000 0.026 0.000 0.026 0.000 vectors.py:9(__init__)
1 0.000 0.000 0.135 0.135 {built-in method builtins.exec}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
Я уже удалил много вещей и упростил код, чтобы напрямую использовать словарь вместо итерации с ключами, я также удалил копии где я мог.
Это код, который был примерно в два раза медленнее
Код: Выделить всё
def vector_addition(self, vector : 'vector2d'):
"""
Returns the sum of the two vectors
"""
add_vector : vector2d = copy.deepcopy(self)
for key in add_vector.components.keys():
add_vector.components[key] += vector.get_components(key)[0]
return add_vector
Подробнее здесь: https://stackoverflow.com/questions/793 ... r-addition
Мобильная версия