2

I'm working as a free time project on a vector class in Python, to test myself. People with enough math background know that a vector can be multiplied by a scalar; 2 * (1, 2) = (2 * 1, 2 * 2) = (2, 4).

This is simple enough to do in, say, C#. public static operator *(int scalar, Vector vector) and go on to define it. But when I try to do the most obvious route in Python, it throws a TypeError at me:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for *: 'int' and 'Vector'

This is also raised when I reverse the order of the operands to Vector * scalar.

Now, I know that, in Python, iterables such as strings can be multiplied: e.g. "abc" * 2 yields "abcabc". My question is: is this only an inherent feature of the language, or is there a way to write multi-type operators?

The code:

class Vector:
        def __init__(self, *contents):
            self.__c = contents

        def __iter__(self):
            return iter(self.__c)

        def __add__(u, v):
            exceptIfUnequal(u, v, "add") # <-- This is just a method that will raise an error if the vectors are unequal, it's unimportant to us
            return Vector(*[a + b for a, b in zip(u, v)])

        def __sub__(u, v):
            exceptIfUnequal(u, v, "subtract")
            return a + (-b)

        def __neg__(u):
            return Vector(-a for a in u)

        def __mult__(k, u):
            return Vector(*[k * a for a in u])
#I'm aware that logistically, k and u will need to be reversed if I want to reverse the order

        def __len__(u):
            return len(u.__c)

        def __str__(self):
            s = "<" + "{}, " * (len(self.__c) - 1) + "{}>"
            return s.format(*self.__c)

So is there anything I can do to make this work? Or is it simply impossible?

EDIT: Wouldn't you know it, it was a silly mistake. The proper Python multiplication is __mul__, not - as I had written - __mult__ -- with a t. But even more particularly, the item I wanted was __rmul__, which allows me to multiply in scalar * vector order.

MutantOctopus
  • 3,431
  • 4
  • 22
  • 31

1 Answers1

0

What you're doing should work, you just have the wrong method name. It should be __mul__.

Although I think it's a little more nuanced if you want to support both int * Vector and Vector * Vector. You're going to need to add a bit more to the method for that.

Read here for more info https://docs.python.org/2/reference/datamodel.html#emulating-numeric-types

dursk
  • 4,435
  • 2
  • 19
  • 30