Reputation: 3
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
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 @classmethod
s; 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
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