# The Spirit of the Assignment

18 Jan 2013I’m lazy. I used to argue that I was merely strategically lazy: that I knew enough about the problem domain to optimize out the rest of the work. Like tonight’s homework in physics, which came down to a lot of operations on vectors such as rotations by arbitrary angles (in degrees OFC) and subsequent additions and soforth. Now vector math isn’t hard at all. I’ve been doing it since high school, however it is laborious and rather easy to muck unless done carefully.

Usually when I encounter a set of problems which involve doing a tedious amount of work by hand I will resort to a program. Such as this one which I just “happen” to have lying around after this latest batch of homework.

```
#!/usr/bin/env python3
import math
class Vector():
def fromXYZ(self, X, Y, Z):
self.__x__ = X
self.__y__ = Y
self.__z__ = Z
def fromPolar2D(self, mag, theta):
self.__z__ = 0
self.__y__ = math.sin(math.radians(theta)) * mag
self.__x__ = math.cos(math.radians(theta)) * mag
def thetaXY(self):
return math.atan(self.__y__/self.__x__)
def rotateX(self, deg):
# Rotates the vector by `deg` degrees on the XY plane.
magXY = math.sqrt(self.__x__**2 + self.__y__**2)
deltaXY = (deg*math.pi)/180.0
theta = self.thetaXY() + deltaXY
self.__y__ = math.sin(theta) * magXY
self.__x__ = math.cos(theta) * magXY
def magnatude(self):
# computes the scalar magnatude of the vector
return math.sqrt(self.__z__**2 +
self.__x__**2+
self.__y__**2)
# this used to be math.sqrt(self.__x__**2+self.__y**2)**2
# but then I realized that's stupid
def normalize(self):
v = Vector()
v.fromXYZ(self.__x__ / self.magnatude(),
self.__y__ / self.magnatude(),
self.__z__ / self.magnatude())
return v
def __add__(self, other):
if(type(other) is Vector):
v = Vector()
v.fromXYZ(self.__x__ + other.__x__,
self.__y__ + other.__y__,
self.__z__ + other.__z__)
return v
else:
raise Exception("can't add HUR DUR")
def __iadd__(self, other):
self = self.__add__(other)
return self
def __sub__(self, other):
return other * -1 + self
def __isub__(self, other):
self = self - other
def __mul__(self, other):
if(type(other) is Vector):
raise Exception("HUR DUR can't do dot product")
else:
v = Vector()
v.fromXYZ(self.__x__ * other,
self.__y__ * other,
self.__z__ * other)
return v
def __imul__(self, other):
self = self.__mul__(other)
return self
def __str__(self):
return "< {0} {1} {2} >".format(self.__x__, self.__y__, self.__z__)
def __repr__(self):
return self.__str__()
```

It isn’t much, and it sure isn’t especially CPU efficient, but cranking out that implementation probably saved me 50% or so of the time I would otherwise have spent crunching the numbers by hand with a calculator. Strictly speaking I was less distracted while doing the homework because the distraction of the moment was productive with regards to completing the assignment.

But it violates the **spirit** of the assignment. The work was
deliberately chosen to hammer into myself and the other physics
students the mech