Code that works with points and directions in the plane is much easier to read when it can say 2 * (u + v) instead of scale(add(u, v), 2). Write a class Vec(x, y) that behaves like a mathematical vector:
repr(v)isVec(x, y)with the components written as Python would write them:Vec(1, 2),Vec(0.5, -3).u + vandu - vadd and subtract componentwise;-vflips both signs.v * k,k * vandv / kscale by a numberk.u == visTruewhen both components are equal; equal vectors must also count as one item in a set.abs(v)is the lengthsqrt(x**2 + y**2), andu.dot(v)isx1*x2 + y1*y2.- A vector can be unpacked:
x, y = v. - Adding a vector and a number is an error:
v + 3raisesTypeError.
Results are always new Vec objects; the operands never change. The setup has the helpers centroid(points), which computes sum(points, Vec(0, 0)) / len(points) with your operators, and raises(fn, *args), which returns the name of the exception a call raises (or None).
Examples
Input: u, v = Vec(1, 2), Vec(3, -1)
u + v, 2 * (u - v), abs(Vec(3, 4)), u.dot(v)
Output: (Vec(4, 1), Vec(-4, 6), 5.0, 1)
Input: centroid([Vec(0, 0), Vec(4, 0), Vec(2, 6)]), len({Vec(1, 2), Vec(1, 2), Vec(2, 1)})
Output: (Vec(2.0, 2.0), 2)
Constraints
- Components are integers or floats;
kis a number andk != 0for division. - The tests compare
reprstrings (so the outputs below are thereprof the results) and use==,set,sorted(..., key=abs)and unpacking.
Goals
- Make `+`, `-`, `*`, `/`, `abs` and `==` work on your own objects
- Give a class a `__repr__` that looks like the code that builds the object
- Keep objects that define `==` usable in sets and as dictionary keys