1 #!/usr/bin/env python3
2
3 """
4 A demonstration of classes and their special methods in Python.
5 """
6
7 class ESC[4;38;5;81mVec:
8 """A simple vector class.
9
10 Instances of the Vec class can be constructed from numbers
11
12 >>> a = Vec(1, 2, 3)
13 >>> b = Vec(3, 2, 1)
14
15 added
16 >>> a + b
17 Vec(4, 4, 4)
18
19 subtracted
20 >>> a - b
21 Vec(-2, 0, 2)
22
23 and multiplied by a scalar on the left
24 >>> 3.0 * a
25 Vec(3.0, 6.0, 9.0)
26
27 or on the right
28 >>> a * 3.0
29 Vec(3.0, 6.0, 9.0)
30
31 and dot product
32 >>> a.dot(b)
33 10
34
35 and printed in vector notation
36 >>> print(a)
37 <1 2 3>
38
39 """
40
41 def __init__(self, *v):
42 self.v = list(v)
43
44 @classmethod
45 def fromlist(cls, v):
46 if not isinstance(v, list):
47 raise TypeError
48 inst = cls()
49 inst.v = v
50 return inst
51
52 def __repr__(self):
53 args = ', '.join([repr(x) for x in self.v])
54 return f'{type(self).__name__}({args})'
55
56 def __str__(self):
57 components = ' '.join([str(x) for x in self.v])
58 return f'<{components}>'
59
60 def __len__(self):
61 return len(self.v)
62
63 def __getitem__(self, i):
64 return self.v[i]
65
66 def __add__(self, other):
67 "Element-wise addition"
68 v = [x + y for x, y in zip(self.v, other.v)]
69 return Vec.fromlist(v)
70
71 def __sub__(self, other):
72 "Element-wise subtraction"
73 v = [x - y for x, y in zip(self.v, other.v)]
74 return Vec.fromlist(v)
75
76 def __mul__(self, scalar):
77 "Multiply by scalar"
78 v = [x * scalar for x in self.v]
79 return Vec.fromlist(v)
80
81 __rmul__ = __mul__
82
83 def dot(self, other):
84 "Vector dot product"
85 if not isinstance(other, Vec):
86 raise TypeError
87 return sum(x_i * y_i for (x_i, y_i) in zip(self, other))
88
89
90 def test():
91 import doctest
92 doctest.testmod()
93
94 test()