quentin
quentin

Reputation: 3

How to add different vectors in vector class? Python

This is one of my first python programs. I cannot operate on vectors created from init with fill_n. I don't know what I should change.

additionally "The inner representation of the vector should not be visible outside the class (protected field)."

class Vector:
    def __init__ (self, lista):
        self.value = lista

    def __add__ (self, other):

        res = Vector( [x + y for x, y in zip(self.value, other.value) ])
        return res

    def __mul__(self, other):
        dot=0
        for x, y in zip(self.value, other.value):
             dot = dot + x *y
        return dot

    def fill_n ( size, val):
        value=[val]*size
        return tuple(value)

    def __str__(self):
        return ', '.join([str(x) for x in self.value])


def main():
    v1 = Vector([1, 2, 3])
    v2 = Vector([4, 2, 2])
    v3 = Vector.fill_n(3,1)

    print (v1 + v2)
    print (v1 + v3) #It doesn't work 
    print(v3)


main()

The error I get is:

Traceback (most recent call last):
  line 34, in <module>
    main()
  line 30, in main
    print (v1 + v3) #It doesn't work
  line 7, in __add__
    res = Vector( [x + y for x, y in zip(self.value, other.value) ])
AttributeError: 'tuple' object has no attribute 'value'

Upvotes: 0

Views: 152

Answers (2)

ShadowRanger
ShadowRanger

Reputation: 155516

fill_n is clearly intended to make a Vector, but as implemented, does nothing of the sort, so you get type conflicts. Make it an alternate constructor with @classmethod, and you'll get the results you want with no other changes:

@classmethod                 # Ensures it passes the class even when called on an instance
def fill_n(cls, size, val):  # Added initial parameter, cls, the actually class called on
    value=[val]*size
    return cls(value)  # Changed from tuple to cls which will be Vector (or a subclass)

As a rule, all alternate constructors should be @classmethods; with @staticmethod, you won't be subclass friendly, with undecorated methods omitting self/cls it only works when called on the class, not an instance (making it harder to construct new instances from the class of an existing instance), and with instance methods, you can't call it on the class.

Upvotes: 1

Random Davis
Random Davis

Reputation: 6857

Technically you only need one change to get this to work; v3 is a tuple of 3 values. You can just pass it to the constructor of Vector and the result will be a proper Vector object that you can add to other vectors, like so:

v3 = Vector(Vector.fill_n(3,1))

Like I said in a comment, the fill_n method doesn't reference the self parameter, so you should put @staticmethod above it. It's not necessary in this case but it'll throw off any kinds of static analyzers or linters that IDEs use:

@staticmethod
    def fill_n(size, val):
        ...

With that taken care of, your script runs fine. Output:

5, 4, 5
2, 3, 4
1, 1, 1

Upvotes: 0

Related Questions