0

I have successfully implemented the inner product like this (its an excercise - some things might beeing imported):

class Point(object):

def __init__(self, x, y):
    self.x = x
    self.y = y
    

def __repr__(self):
    return 'Point({}, {})'.format(self.x, self.y)


def __add__(self, point):
    return Point(self.x + point.x, self.y + point.y)
    
            
def __sub__(self, point):
    return Point(self.x - point.x, self.y - point.y)


def __mul__(self, second):
    if isinstance(second, Point):
        return (self.x * second.x + self.y * second.y)
    elif isinstance(second, int):
        return Point(self.x * second, self.y * second)
    elif isinstance(second, float):
        return Point(self.x * second, self.y * second)
    
def __mul__(first, self):
    if isinstance(first, int) and isinstance(self, Point):
        return Point(self.x * first, self.y * first)
    elif isinstance(first, float) and isinstance(self, Point):
        return Point(self.x * first, self.y * first)

I get an error if I execute say

p=Point(3.7,4.8)
print(p*3)

Without the last block (scalar mult. from the left) the outout is correct. Surely there is an error in the last block cause

p=Point(3.7,4.8)
print(3*p)

(which the last block is for) also is not working.

Hope someone can help - thanks!

3 Answers3

0

When you get an error or unexpected output with certain commands, please make sure to include that error/output so other people can better understand what's going on.

In your code, you've defined __mul__ twice; thus the second definition overwrites the first one. I think what you may have meant was to define __mul__ and also __rmul__. Additionally, you're introducing some unnecessary conditions in your if statements. Here's a suggestion:

def __mul__(self, second):
    if isinstance(second, Point):
        return (self.x * second.x + self.y * second.y)
    elif isinstance(second, int) or isinstance(second, float):
        return Point(self.x * second, self.y * second)
    
def __rmul__(self, first):
    # no need to confirm that self is an instance of Point
    # since we're inside a method of class Point anyway
    if isinstance(first, int) or isinstance(first, float):
        return Point(self.x * first, self.y * first)

That should solve it, let me know if it doesn't.

David Husz
  • 48
  • 4
  • Thanks for your quick answer. I think the problem ist the "r" in `__rmul__` . I first wrote `__mult__` instead of `__mul__` in my code and got an error for the part that was already working right now(scalar multiplication from the right which is the `def __mul__(self, second): ...` code block – latex101 Jul 20 '20 at 09:05
0
class Point(object):

def __init__(self, x, y):
    self.x = x
    self.y = y
    

def __repr__(self):
    return 'Point({}, {})'.format(self.x, self.y)


def __add__(self, point):
    return Point(self.x + point.x, self.y + point.y)
    
            
def __sub__(self, point):
    return Point(self.x - point.x, self.y - point.y)



def __mul__(self, second):
    if isinstance(second, Point):
        return (self.x * second.x + self.y * second.y)
    elif isinstance(second, int) or isinstance(second, float):
        return Point(self.x * second, self.y * second)

def __rmul__(first, self):
# no need to confirm that self is an instance of Point
# since we're inside a method of class Point anyway
    if isinstance(first, int) or isinstance(first, float):
        return Point(self.x * first, self.y * first)

p=Point(3.7,4.8)
print(p*3)
print(p*3.5)
print(3*p)
print(3.5*p)

leads to output

Point(11.100000000000001, 14.399999999999999)
Point(12.950000000000001, 16.8)
None
None
0

I see, you have mixed up the arguments in the definition of __rmul__. self should always be the first argument (because it is implicitly passed as the first argument), so instead of

def __rmul__(first, self):

write

def __rmul__(self, first):
David Husz
  • 48
  • 4
  • Thank you, thats the solution. It works with this code block: ` def __rmul__(self, first): if isinstance(first, int) and isinstance(self, Point): return Point(self.x * first, self.y * first) elif isinstance(first, float) and isinstance(self, Point): return Point(self.x * first, self.y * first)` However I wonder why something different from`__mul__` works since this fuction specifies what to do with the `*` oprator right? – latex101 Jul 20 '20 at 10:41
  • Now I know why: `__rmul__(self, other)` implements the so-called reflected multiplication. – latex101 Jul 20 '20 at 14:42