## pyx-checkins

 [PyX-checkins] pyx/test/experimental solve.py,1.5,1.6 test_solve.py,1.1,1.2 From: André Wobst - 2004-08-01 15:12:46 ```Update of /cvsroot/pyx/pyx/test/experimental In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11338 Modified Files: solve.py test_solve.py Log Message: make addend to always be a scalar Index: solve.py =================================================================== RCS file: /cvsroot/pyx/pyx/test/experimental/solve.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** solve.py 30 Jul 2004 20:05:27 -0000 1.5 --- solve.py 1 Aug 2004 15:12:37 -0000 1.6 *************** *** 21,24 **** --- 21,25 ---- # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + import Numeric, LinearAlgebra *************** *** 27,55 **** # represents a scalar variable or constant ! def __init__(self, value=None, varname="unnamed_scalar"): ! self.value = None if value is not None: self.set(value) ! self.varname = varname def addend(self): ! return addend([self], None) ! def term(self): ! return term([self.addend()]) def __add__(self, other): ! return self.term() + other __radd__ = __add__ def __sub__(self, other): ! return self.term() - other def __rsub__(self, other): ! return -self.term() + other ! ! def __neg__(self): ! return -self.addend() def __mul__(self, other): --- 28,59 ---- # represents a scalar variable or constant ! def __init__(self, value=None, name="unnamed_scalar"): ! self._scalar = None if value is not None: self.set(value) ! self.name = name ! ! def scalar(self): ! return self def addend(self): ! return addend([self]) ! def polynom(self): ! return self.addend().polynom() ! ! def __neg__(self): ! return -self.addend() def __add__(self, other): ! return self.polynom() + other __radd__ = __add__ def __sub__(self, other): ! return self.polynom() - other def __rsub__(self, other): ! return -self.polynom() + other def __mul__(self, other): *************** *** 62,72 **** def is_set(self): ! return self.value is not None def set(self, value): if self.is_set(): ! raise RuntimeError("variable already defined") try: ! self.value = float(value) except: raise RuntimeError("float expected") --- 66,76 ---- def is_set(self): ! return self._scalar is not None def set(self, value): if self.is_set(): ! raise RuntimeError("scalar already defined") try: ! self._scalar = float(value) except: raise RuntimeError("float expected") *************** *** 74,322 **** def get(self): if not self.is_set(): ! raise RuntimeError("variable not yet defined") ! return self.value ! ! def __str__(self): ! if self.is_set(): ! return "%s{=%s}" % (self.varname, self.value) ! else: ! return self.varname def __float__(self): return self.get() - class vector: - # represents a vector, i.e. a list of scalars - - def __init__(self, dimension_or_values, varname="unnamed_vector"): - try: - varname + "" - except TypeError: - raise RuntimeError("a vectors varname should be a string (you probably wanted to write vector([x, y]) instead of vector(x, y))") - try: - # values - self.scalars = [scalar(value=value, varname="%s[%i]" % (varname, i)) - for i, value in enumerate(dimension_or_values)] - except (TypeError, AttributeError): - # dimension - self.scalars = [scalar(varname="%s[%i]" % (varname, i)) - for i in range(dimension_or_values)] - self.varname = varname - - def __len__(self): - return len(self.scalars) ! def __getitem__(self, i): ! return self.scalars[i] ! def __getattr__(self, attr): ! if attr == "x": ! return self[0] ! if attr == "y": ! return self[1] ! if attr == "z": ! return self[2] ! else: ! raise AttributeError(attr) def addend(self): ! return addend([], self) ! def term(self): ! return term([self.addend()]) def __add__(self, other): ! return self.term() + other __radd__ = __add__ def __sub__(self, other): ! return self.term() - other def __rsub__(self, other): ! return -self.term() + other ! ! def __neg__(self): ! return -self.addend() def __mul__(self, other): ! return self.addend()*other __rmul__ = __mul__ def __div__(self, other): ! return self.addend()/other ! ! def __str__(self): ! return "%s{=(%s)}" % (self.varname, ", ".join([str(scalar) for scalar in self.scalars])) ! ! ! class addend: ! # represents an addend of a term, i.e. a list of scalars and ! # optionally a vector (for a vector term) otherwise the vector ! # is None ! ! def __init__(self, scalars, vector): ! # self.vector might be None for a scalar addend ! self.scalars = scalars ! self.vector = vector ! ! def __len__(self): ! return len(self.vector) ! ! def __getitem__(self, i): ! return addend(self.scalars + [self.vector[i]], None) ! ! def addend(self): ! return self ! def term(self): ! return term([self.addend()]) def is_linear(self): ! assert self.vector is None ! return len([scalar for scalar in self.scalars if not scalar.is_set()]) < 2 def prefactor(self): assert self.is_linear() ! prefactor = 1 ! for scalar_set in [scalar for scalar in self.scalars if scalar.is_set()]: ! prefactor *= scalar_set.get() ! return prefactor def variable(self): assert self.is_linear() ! try: ! variable, = [scalar for scalar in self.scalars if not scalar.is_set()] ! except ValueError: ! return None else: ! return variable def __add__(self, other): ! return self.term() + other __radd__ = __add__ def __sub__(self, other): ! return self.term() - other def __rsub__(self, other): ! return -self.term() + other ! ! def __neg__(self): ! return addend([scalar(-1)] + self.scalars, self.vector) def __mul__(self, other): ! try: ! a = other.addend() ! except (TypeError, AttributeError): ! try: ! t = other.term() ! except (TypeError, AttributeError): ! return self*scalar(other) ! else: ! return term([self*a for a in t.addends]) ! else: ! if a.vector is not None: ! if self.vector is not None: ! if len(self.vector) != len(a.vector): ! raise RuntimeError("vector length mismatch in scalar product") ! return term([addend(self.scalars + a.scalars + [x*y], None) ! for x, y in zip(self.vector, a.vector)]) ! else: ! return addend(self.scalars + a.scalars, a.vector) ! else: ! return addend(self.scalars + a.scalars, self.vector) __rmul__ = __mul__ def __div__(self, other): ! return addend([scalar(1/other)] + self.scalars, self.vector) def __str__(self): ! scalarstring = " * ".join([str(scalar) for scalar in self.scalars]) ! if self.vector is None: ! return scalarstring ! else: ! if len(scalarstring): ! scalarstring += " * " ! return scalarstring + str(self.vector) - class term: - # represents a term, i.e. a list of addends ! def __init__(self, addends): ! assert len(addends) try: ! self.length = len(addends[0]) ! except (TypeError, AttributeError): ! for addend in addends[1:]: ! try: ! len(addend) ! except (TypeError, AttributeError): ! pass ! else: ! raise RuntimeError("vector addend in scalar term") ! self.length = None else: ! for addend in addends[1:]: try: ! l = len(addend) except (TypeError, AttributeError): ! raise RuntimeError("scalar addend in vector term") ! if l != self.length: ! raise RuntimeError("vector length mismatch in term constructor") ! self.addends = addends def __len__(self): ! if self.length is None: ! raise AttributeError("scalar term") ! else: ! return self.length def __getitem__(self, i): ! return term([addend[i] for addend in self.addends]) ! def term(self): return self ! def is_linear(self): ! is_linear = 1 ! for addend in self.addends: ! is_linear = is_linear and addend.is_linear() ! return is_linear def __add__(self, other): ! try: ! t = other.term() ! except: ! return self + scalar(other) ! else: ! return term(self.addends + t.addends) __radd__ = __add__ - def __neg__(self): - return term([-addend for addend in self.addends]) - def __sub__(self, other): ! return -other+self def __rsub__(self, other): ! return -self+other def __mul__(self, other): ! return term([addend*other for addend in self.addends]) __rmul__ = __mul__ def __div__(self, other): ! return term([addend/other for addend in self.addends]) def __str__(self): ! return " + ".join([str(addend) for addend in self.addends]) --- 78,319 ---- def get(self): if not self.is_set(): ! raise RuntimeError("scalar not yet defined") ! return self._scalar def __float__(self): return self.get() + def __str__(self): + if self.is_set(): + return "%s{=%s}" % (self.name, self._scalar) + else: + return self.name ! class addend: ! # represents a addend, i.e. list of scalars to be multiplied by each other ! def __init__(self, scalars): ! self._scalars = [scalar.scalar() for scalar in scalars] ! if not len(self._scalars): ! raise RuntimeError("empty scalars not allowed") def addend(self): ! return self ! def polynom(self): ! return polynom([self]) ! ! def __neg__(self): ! return addend([scalar(-1)] + self._scalars) def __add__(self, other): ! return self.polynom() + other __radd__ = __add__ def __sub__(self, other): ! return self.polynom() - other def __rsub__(self, other): ! return -self.polynom() + other def __mul__(self, other): ! try: ! other = other.addend() ! except (TypeError, AttributeError): ! try: ! other = scalar(other) ! except RuntimeError: ! return other * self ! else: ! return addend(self._scalars + [other]) ! else: ! return addend(self._scalars + other._scalars) __rmul__ = __mul__ def __div__(self, other): ! return addend([scalar(1/other)] + self._scalars) ! def __float__(self): ! product = float(self._scalars[0]) ! for scalar in self._scalars[1:]: ! product *= float(scalar) ! return product def is_linear(self): ! return len([scalar for scalar in self._scalars if not scalar.is_set()]) < 2 def prefactor(self): assert self.is_linear() ! setscalars = [scalar for scalar in self._scalars if scalar.is_set()] ! if len(setscalars): ! return float(addend(setscalars)) ! else: ! return 1 def variable(self): assert self.is_linear() ! unsetscalars = [scalar for scalar in self._scalars if not scalar.is_set()] ! if len(unsetscalars): ! assert len(unsetscalars) == 1 ! return unsetscalars[0] else: ! return None ! ! def __str__(self): ! return " * ".join([str(scalar) for scalar in self._scalars]) ! ! ! class polynom: ! # represents a polynom, i.e. a list of addends to be summed up ! ! def __init__(self, polynom): ! self._addends = [addend.addend() for addend in polynom] ! if not len(self._addends): ! raise RuntimeError("empty polynom not allowed") ! ! def polynom(self): ! return self ! ! def __neg__(self): ! return polynom([-addend for addend in self._addends]) def __add__(self, other): ! try: ! other = other.polynom() ! except (TypeError, AttributeError): ! other = scalar(other).polynom() ! return polynom(self._addends + other._addends) __radd__ = __add__ def __sub__(self, other): ! return -other + self def __rsub__(self, other): ! return -self + other def __mul__(self, other): ! sum = self._addends[0]*other ! for addend in self._addends[1:]: ! sum += addend*other ! return sum __rmul__ = __mul__ def __div__(self, other): ! return polynom([addend/other for addend in self._addends]) ! ! def __float__(self): ! sum = float(self._addends[0]) ! for addend in self._addends[1:]: ! sum += float(addend) ! return sum ! ! def is_linear(self): ! is_linear = 1 ! for addend in self._addends: ! is_linear = is_linear and addend.is_linear() ! return is_linear def __str__(self): ! return " + ".join([str(addend) for addend in self._addends]) + def solve(self, solver): + solver.addequation(self) ! class vector: ! # represents a vector, i.e. a list of terms ! ! def __init__(self, dimension_or_values, name="unnamed_vector"): try: ! name + "" ! except TypeError: ! raise RuntimeError("a vectors name should be a string (you probably wanted to write vector([x, y]) instead of vector(x, y))") ! try: ! for value in dimension_or_values: ! pass ! except: ! # dimension ! self._items = [scalar(name="%s[%i]" % (name, i)) ! for i in range(dimension_or_values)] else: ! # values ! self._items = [] ! for value in dimension_or_values: try: ! value.polynom() except (TypeError, AttributeError): ! self._items.append(scalar(value=value, name="%s[%i]" % (name, len(self._items)))) ! else: ! self._items.append(value) ! if not len(self._items): ! raise RuntimeError("empty vector not allowed") ! self.name = name def __len__(self): ! return len(self._items) def __getitem__(self, i): ! return self._items[i] ! def __getattr__(self, attr): ! if attr == "x": ! return self[0] ! if attr == "y": ! return self[1] ! if attr == "z": ! return self[2] ! else: ! raise AttributeError(attr) ! ! def vector(self): return self ! def __neg__(self): ! return vector([-item for item in self._items]) def __add__(self, other): ! other = other.vector() ! if len(self) != len(other): ! raise RuntimeError("vector length mismatch in add") ! return vector([selfitem + otheritem for selfitem, otheritem in zip(self._items, other._items)]) __radd__ = __add__ def __sub__(self, other): ! return -other + self def __rsub__(self, other): ! return -self + other def __mul__(self, other): ! try: ! other = other.vector() ! except (TypeError, AttributeError): ! return vector([item*other for item in self._items]) ! else: ! # scalar product ! if len(self) != len(other): ! raise RuntimeError("vector length mismatch in scalar product") ! sum = self._items[0]*other._items[0] ! for selfitem, otheritem in zip(self._items[1:], other._items[1:]): ! sum += selfitem*otheritem ! return sum __rmul__ = __mul__ def __div__(self, other): ! return vector([item/other for item in self._items]) def __str__(self): ! return "%s{=(%s)}" % (self.name, ", ".join([str(item) for item in self._items])) ! ! def solve(self, solver): ! for item in self._items: ! solver.addequation(item) *************** *** 325,329 **** def __init__(self): ! self.eqs = [] # scalar equations not yet solved (a equation is a term to be zero here) def eq(self, lhs, rhs=None): --- 322,326 ---- def __init__(self): ! self.eqs = [] # scalar equations not yet solved (a equation is a polynom to be zero) def eq(self, lhs, rhs=None): *************** *** 332,350 **** else: eq = lhs - rhs ! eq = eq.term() ! try: ! # is it a vector equation? ! neqs = len(eq) ! except (TypeError, AttributeError): ! self.add(eq) ! else: ! for i in range(neqs): ! self.add(eq[i]) ! def add(self, equation): ! # the equation is just a term which should be zero ! self.eqs.append(equation) ! # try to solve some combinations of equations while 1: for eqs in self.combine(self.eqs): --- 329,339 ---- else: eq = lhs - rhs ! eq.solve(self) ! def addequation(self, equation): ! # the equation is just a polynom which should be zero ! self.eqs.append(equation.polynom()) ! # try to solve some combinations of linear equations while 1: for eqs in self.combine(self.eqs): *************** *** 371,375 **** vars = [] for eq in eqs: ! for addend in eq.addends: var = addend.variable() if var is not None and var not in vars: --- 360,364 ---- vars = [] for eq in eqs: ! for addend in eq._addends: var = addend.variable() if var is not None and var not in vars: *************** *** 379,383 **** b = Numeric.zeros((l, )) for i, eq in enumerate(eqs): ! for addend in eq.addends: var = addend.variable() if var is not None: --- 368,372 ---- b = Numeric.zeros((l, )) for i, eq in enumerate(eqs): ! for addend in eq._addends: var = addend.variable() if var is not None: Index: test_solve.py =================================================================== RCS file: /cvsroot/pyx/pyx/test/experimental/test_solve.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_solve.py 30 Jul 2004 20:05:27 -0000 1.1 --- test_solve.py 1 Aug 2004 15:12:37 -0000 1.2 *************** *** 9,35 **** self.failUnlessRaises(RuntimeError, scalar, 1j) self.failUnlessEqual(str(scalar()), "unnamed_scalar") ! self.failUnlessEqual(str(scalar(varname="s")), "s") self.failUnlessEqual(str(scalar(1)), "unnamed_scalar{=1.0}") ! self.failUnlessEqual(str(scalar(-1, varname="s")), "s{=-1.0}") def testMath(self): ! self.failUnlessEqual(str(-scalar(varname="s")), "unnamed_scalar{=-1.0} * s") ! self.failUnlessEqual(str(scalar(varname="s") + scalar(varname="t")), "s + t") ! self.failUnlessEqual(str(scalar(varname="s") + 1), "s + unnamed_scalar{=1.0}") ! self.failUnlessEqual(str(1 + scalar(varname="s")), "s + unnamed_scalar{=1.0}") ! self.failUnlessEqual(str(scalar(varname="s") - scalar(varname="t")), "unnamed_scalar{=-1.0} * t + s") ! self.failUnlessEqual(str(1 - scalar(varname="s")), "unnamed_scalar{=-1.0} * s + unnamed_scalar{=1.0}") ! self.failUnlessEqual(str(2 * scalar(varname="s")), "s * unnamed_scalar{=2.0}") ! self.failUnlessEqual(str(scalar(varname="s") * 2), "s * unnamed_scalar{=2.0}") ! self.failUnlessEqual(str(scalar(varname="s") * scalar(varname="t")), "s * t") ! self.failUnlessEqual(str(scalar(varname="s") / 2.0), "unnamed_scalar{=0.5} * s") ! self.failUnlessEqual(str(scalar(varname="s") / 2), "unnamed_scalar{=0.0} * s") # integer logic! self.failUnlessRaises(TypeError, lambda: 2 / scalar()) self.failUnlessRaises(TypeError, lambda: scalar() / scalar()) self.failUnlessRaises(TypeError, lambda: vector(1) / scalar()) ! self.failUnlessRaises(TypeError, lambda: (scalar() + scalar()) / scalar()) self.failUnlessRaises(TypeError, lambda: (vector(1) + vector(1)) / scalar()) ! def testSetGetIs_Set(self): s = scalar() self.failUnlessEqual(s.is_set(), 0) --- 9,37 ---- self.failUnlessRaises(RuntimeError, scalar, 1j) self.failUnlessEqual(str(scalar()), "unnamed_scalar") ! self.failUnlessEqual(str(scalar(name="s")), "s") self.failUnlessEqual(str(scalar(1)), "unnamed_scalar{=1.0}") ! self.failUnlessEqual(str(scalar(-1, name="s")), "s{=-1.0}") def testMath(self): ! self.failUnlessEqual(str(-scalar(name="s")), "unnamed_scalar{=-1.0} * s") ! self.failUnlessEqual(str(scalar(name="s") + scalar(name="t")), "s + t") ! self.failUnlessEqual(str(scalar(name="s") + 1), "s + unnamed_scalar{=1.0}") ! self.failUnlessEqual(str(1 + scalar(name="s")), "s + unnamed_scalar{=1.0}") ! self.failUnlessEqual(str(scalar(name="s") - scalar(name="t")), "unnamed_scalar{=-1.0} * t + s") ! self.failUnlessEqual(str(1 - scalar(name="s")), "unnamed_scalar{=-1.0} * s + unnamed_scalar{=1.0}") ! self.failUnlessEqual(str(2 * scalar(name="s")), "s * unnamed_scalar{=2.0}") ! self.failUnlessEqual(str(scalar(name="s") * 2), "s * unnamed_scalar{=2.0}") ! self.failUnlessEqual(str(scalar(name="s") * scalar(name="t")), "s * t") ! self.failUnlessEqual(str((scalar(name="s") + scalar(name="t")) * 2), "s * unnamed_scalar{=2.0} + t * unnamed_scalar{=2.0}") ! self.failUnlessEqual(str(scalar(name="s") / 2.0), "unnamed_scalar{=0.5} * s") ! self.failUnlessEqual(str(scalar(name="s") / 2), "unnamed_scalar{=0.0} * s") # integer logic! ! self.failUnlessEqual(str((scalar(name="s") + scalar(name="t")) / 2.0), "unnamed_scalar{=0.5} * s + unnamed_scalar{=0.5} * t") self.failUnlessRaises(TypeError, lambda: 2 / scalar()) self.failUnlessRaises(TypeError, lambda: scalar() / scalar()) self.failUnlessRaises(TypeError, lambda: vector(1) / scalar()) ! self.failUnlessRaises(TypeError, lambda: ((scalar() + scalar()) / scalar())) self.failUnlessRaises(TypeError, lambda: (vector(1) + vector(1)) / scalar()) ! def testAccess(self): s = scalar() self.failUnlessEqual(s.is_set(), 0) *************** *** 136,164 **** def testLen(self): ! for i in range(10): a = vector(i) self.failUnlessEqual(len(a), i) self.failUnlessEqual(str(a), "unnamed_vector{=(" + ", ".join(["unnamed_vector[%i]" % j for j in range(i)]) + ")}") ! for i in range(10): a = -vector(i) self.failUnlessEqual(len(a), i) ! self.failUnlessEqual(str(a), "unnamed_scalar{=-1.0} * unnamed_vector{=(" + ", ".join(["unnamed_vector[%i]" % j for j in range(i)]) + ")}") def testMath(self): ! self.failUnlessEqual(str(-vector(1, "a")), "unnamed_scalar{=-1.0} * a{=(a[0])}") ! self.failUnlessEqual(str(vector(1, "a") + vector(1, "t")), "a{=(a[0])} + t{=(t[0])}") ! self.failUnlessRaises(RuntimeError, operator.__add__, vector(1), scalar()) ! self.failUnlessRaises(RuntimeError, operator.__add__, vector(1), vector(2)) ! self.failUnlessEqual(str(vector(1, "a") - vector(1, "t")), "unnamed_scalar{=-1.0} * t{=(t[0])} + a{=(a[0])}") ! self.failUnlessRaises(RuntimeError, operator.__sub__, vector(1), scalar()) ! self.failUnlessRaises(RuntimeError, operator.__sub__, vector(1), vector(2)) ! self.failUnlessEqual(str(2 * vector(1, "a")), "unnamed_scalar{=2.0} * a{=(a[0])}") ! self.failUnlessEqual(str(vector(1, "a") * 2), "unnamed_scalar{=2.0} * a{=(a[0])}") ! self.failUnlessEqual(str(scalar(varname="s") * vector(1, "a")), "s * a{=(a[0])}") ! self.failUnlessEqual(str(vector(1, "a") * scalar(varname="s")), "s * a{=(a[0])}") self.failUnlessEqual(str(vector(2, "a") * vector(2, "b")), "a[0] * b[0] + a[1] * b[1]") ! self.failUnlessRaises(RuntimeError, operator.__mul__, vector(1, "a"), vector(2)) ! self.failUnlessEqual(str(vector(1, "a") / 2.0), "unnamed_scalar{=0.5} * a{=(a[0])}") ! self.failUnlessEqual(str(vector(1, "a") / 2), "unnamed_scalar{=0.0} * a{=(a[0])}") # integer logic! self.failUnlessRaises(TypeError, lambda: scalar() / vector(1)) self.failUnlessRaises(TypeError, lambda: vector(1) / vector(1)) --- 138,166 ---- def testLen(self): ! for i in range(1, 10): a = vector(i) self.failUnlessEqual(len(a), i) self.failUnlessEqual(str(a), "unnamed_vector{=(" + ", ".join(["unnamed_vector[%i]" % j for j in range(i)]) + ")}") ! for i in range(1, 10): a = -vector(i) self.failUnlessEqual(len(a), i) ! self.failUnlessEqual(str(a), "unnamed_vector{=(" + ", ".join(["unnamed_scalar{=-1.0} * unnamed_vector[%i]" % j for j in range(i)]) + ")}") def testMath(self): ! self.failUnlessEqual(str(-vector(2, "a")), "unnamed_vector{=(unnamed_scalar{=-1.0} * a[0], unnamed_scalar{=-1.0} * a[1])}") ! self.failUnlessEqual(str(vector(2, "a") + vector(2, "t")), "unnamed_vector{=(a[0] + t[0], a[1] + t[1])}") ! self.failUnlessRaises(AttributeError, operator.__add__, vector(2), scalar()) ! self.failUnlessRaises(RuntimeError, operator.__add__, vector(2), vector(3)) ! self.failUnlessEqual(str(vector(2, "a") - vector(2, "t")), "unnamed_vector{=(unnamed_scalar{=-1.0} * t[0] + a[0], unnamed_scalar{=-1.0} * t[1] + a[1])}") ! self.failUnlessRaises(RuntimeError, operator.__sub__, vector(2), scalar()) ! self.failUnlessRaises(RuntimeError, operator.__sub__, vector(2), vector(3)) ! self.failUnlessEqual(str(2 * vector(2, "a")), "unnamed_vector{=(a[0] * unnamed_scalar{=2.0}, a[1] * unnamed_scalar{=2.0})}") ! self.failUnlessEqual(str(vector(2, "a") * 2), "unnamed_vector{=(a[0] * unnamed_scalar{=2.0}, a[1] * unnamed_scalar{=2.0})}") ! self.failUnlessEqual(str(scalar(name="s") * vector(2, "a")), "unnamed_vector{=(a[0] * s, a[1] * s)}") ! self.failUnlessEqual(str(vector(2, "a") * scalar(name="s")), "unnamed_vector{=(a[0] * s, a[1] * s)}") self.failUnlessEqual(str(vector(2, "a") * vector(2, "b")), "a[0] * b[0] + a[1] * b[1]") ! self.failUnlessRaises(RuntimeError, operator.__mul__, vector(2, "a"), vector(3)) ! self.failUnlessEqual(str(vector(2, "a") / 2.0), "unnamed_vector{=(unnamed_scalar{=0.5} * a[0], unnamed_scalar{=0.5} * a[1])}") ! self.failUnlessEqual(str(vector(2, "a") / 2), "unnamed_vector{=(unnamed_scalar{=0.0} * a[0], unnamed_scalar{=0.0} * a[1])}") # integer logic! self.failUnlessRaises(TypeError, lambda: scalar() / vector(1)) self.failUnlessRaises(TypeError, lambda: vector(1) / vector(1)) ```