Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/fontTools/misc/vector.py: 47%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

83 statements  

1from numbers import Number 

2import math 

3import operator 

4import warnings 

5 

6 

7__all__ = ["Vector"] 

8 

9 

10class Vector(tuple): 

11 """A math-like vector. 

12 

13 Represents an n-dimensional numeric vector. ``Vector`` objects support 

14 vector addition and subtraction, scalar multiplication and division, 

15 negation, rounding, and comparison tests. 

16 """ 

17 

18 __slots__ = () 

19 

20 def __new__(cls, values, keep=False): 

21 if keep is not False: 

22 warnings.warn( 

23 "the 'keep' argument has been deprecated", 

24 DeprecationWarning, 

25 ) 

26 if type(values) == Vector: 

27 # No need to create a new object 

28 return values 

29 return super().__new__(cls, values) 

30 

31 def __repr__(self): 

32 return f"{self.__class__.__name__}({super().__repr__()})" 

33 

34 def _vectorOp(self, other, op): 

35 if isinstance(other, Vector): 

36 assert len(self) == len(other) 

37 return self.__class__(op(a, b) for a, b in zip(self, other)) 

38 if isinstance(other, Number): 

39 return self.__class__(op(v, other) for v in self) 

40 raise NotImplementedError() 

41 

42 def _scalarOp(self, other, op): 

43 if isinstance(other, Number): 

44 return self.__class__(op(v, other) for v in self) 

45 raise NotImplementedError() 

46 

47 def _unaryOp(self, op): 

48 return self.__class__(op(v) for v in self) 

49 

50 def __add__(self, other): 

51 return self._vectorOp(other, operator.add) 

52 

53 __radd__ = __add__ 

54 

55 def __sub__(self, other): 

56 return self._vectorOp(other, operator.sub) 

57 

58 def __rsub__(self, other): 

59 return self._vectorOp(other, _operator_rsub) 

60 

61 def __mul__(self, other): 

62 return self._scalarOp(other, operator.mul) 

63 

64 __rmul__ = __mul__ 

65 

66 def __truediv__(self, other): 

67 return self._scalarOp(other, operator.truediv) 

68 

69 def __rtruediv__(self, other): 

70 return self._scalarOp(other, _operator_rtruediv) 

71 

72 def __pos__(self): 

73 return self._unaryOp(operator.pos) 

74 

75 def __neg__(self): 

76 return self._unaryOp(operator.neg) 

77 

78 def __round__(self, *, round=round): 

79 return self._unaryOp(round) 

80 

81 def __eq__(self, other): 

82 if isinstance(other, list): 

83 # bw compat Vector([1, 2, 3]) == [1, 2, 3] 

84 other = tuple(other) 

85 return super().__eq__(other) 

86 

87 def __ne__(self, other): 

88 return not self.__eq__(other) 

89 

90 def __bool__(self): 

91 return any(self) 

92 

93 __nonzero__ = __bool__ 

94 

95 def __abs__(self): 

96 return math.sqrt(sum(x * x for x in self)) 

97 

98 def length(self): 

99 """Return the length of the vector. Equivalent to abs(vector).""" 

100 return abs(self) 

101 

102 def normalized(self): 

103 """Return the normalized vector of the vector.""" 

104 return self / abs(self) 

105 

106 def dot(self, other): 

107 """Performs vector dot product, returning the sum of 

108 ``a[0] * b[0], a[1] * b[1], ...``""" 

109 assert len(self) == len(other) 

110 return sum(a * b for a, b in zip(self, other)) 

111 

112 # Deprecated methods/properties 

113 

114 def toInt(self): 

115 warnings.warn( 

116 "the 'toInt' method has been deprecated, use round(vector) instead", 

117 DeprecationWarning, 

118 ) 

119 return self.__round__() 

120 

121 @property 

122 def values(self): 

123 warnings.warn( 

124 "the 'values' attribute has been deprecated, use " 

125 "the vector object itself instead", 

126 DeprecationWarning, 

127 ) 

128 return list(self) 

129 

130 @values.setter 

131 def values(self, values): 

132 raise AttributeError( 

133 "can't set attribute, the 'values' attribute has been deprecated", 

134 ) 

135 

136 def isclose(self, other: "Vector", **kwargs) -> bool: 

137 """Return True if the vector is close to another Vector.""" 

138 assert len(self) == len(other) 

139 return all(math.isclose(a, b, **kwargs) for a, b in zip(self, other)) 

140 

141 

142def _operator_rsub(a, b): 

143 return operator.sub(b, a) 

144 

145 

146def _operator_rtruediv(a, b): 

147 return operator.truediv(b, a)