Python Vector Class no attribute error

Click For Summary
SUMMARY

The forum discussion addresses an AttributeError encountered when attempting to call a non-existent 'add' method on a Vec3 class instance in Python. The Vec3 class, which represents a three-dimensional vector, includes an overloaded addition operator defined by the __add__ method. Users must utilize the '+' operator for addition instead of directly calling 'add' to avoid this error. The discussion clarifies that the correct usage of the class is crucial for proper functionality.

PREREQUISITES
  • Understanding of Python class structures and methods
  • Familiarity with operator overloading in Python
  • Knowledge of basic vector mathematics
  • Experience with Python's exception handling
NEXT STEPS
  • Explore Python operator overloading techniques
  • Learn about Python's special methods (dunder methods) like __add__ and __getitem__
  • Investigate best practices for designing custom classes in Python
  • Study vector mathematics and its applications in programming
USEFUL FOR

Python developers, software engineers, and anyone interested in implementing vector mathematics in their applications will benefit from this discussion.

clope023
Messages
990
Reaction score
130
Hello all, my issue is in calling the attributes of a 3d vector class in python, this is the class I was working with:

import math

class Vec3:
''' A three dimensional vector '''
def __init__(self, v_x=0, v_y=0, v_z=0):
self.set( v_x, v_y, v_z )
def set(self, v_x=0, v_y=0, v_z=0):
if isinstance(v_x, tuple) or isinstance(v_x, list):
self.x, self.y, self.z = v_x
else:
self.x = v_x
self.y = v_y
self.z = v_z
def __getitem__(self, index):
if index==0: return self.x
elif index==1: return self.y
elif index==2: return self.z
else: raise IndexError("index out of range for Vec3")
def __mul__(self, other):
'''Multiplication, supports types Vec3 and other
types that supports the * operator '''
if isinstance(other, Vec3):
return Vec3(self.x*other.x, self.y*other.y, self.z*other.z)
else: #Raise an exception if not a float or integer
return Vec3(self.x*other, self.y*other, self.z*other)
def __div__(self, other):
'''Division, supports types Vec3 and other
types that supports the / operator '''
if isinstance(other, Vec3):
return Vec3(self.x/other.x, self.y/other.y, self.z/other.z)
else: #Raise an exception if not a float or integer
return Vec3(self.x/other, self.y/other, self.z/other)
def __add__(self, other):
'''Addition, supports types Vec3 and other
types that supports the + operator '''
if isinstance(other, Vec3):
return Vec3( self.x + other.x, self.y + other.y, self.z + other.z )
else: #Raise an exception if not a float or integer
return Vec3(self.x + other, self.y + other, self.z + other)
def __sub__(self, other):
'''Subtraction, supports types Vec3 and other
types that supports the - operator '''
if isinstance(other, Vec3):
return Vec3(self.x - other.x, self.y - other.y, self.z - other.z)
else: #Raise an exception if not a float or integer
return Vec3(self.x - other, self.y - other, self.z - other )
def __abs__(self):
'''Absolute value: the abs() method '''
return Vec3( abs(self.x), abs(self.y), abs(self.z) )
def __neg__(self):
'''Negate this vector'''
return Vec3( -self.x, -self.y, -self.z )
def __str__(self):
return '<' + ','.join(
[str(val) for val in (self.x, self.y, self.z) ] ) + '>'
def __repr__(self):
return str(self) + ' instance at 0x' + str(hex(id(self))[2:].upper())
def length(self):
''' This vectors length'''
return math.sqrt( self.x**2 + self.y**2 + self.z**2 )
def length_squared(self):
''' Returns this vectors length squared
(saves a sqrt call, usefull for vector comparisons)'''
return self.x**2 + self.y**2 + self.z**2
def cross(self, other):
'''Return the cross product of this and another Vec3'''
return Vec3( self.y*other.z - other.y*self.z,
self.z*other.x - other.z*self.x,
self.x*other.y - self.y*other.x )
def dot(self, other):
'''Return the dot product of this and another Vec3'''
return self.x*other.x + self.y*other.y + self.z*other.z
def normalized(self):
'''Return this vector normalized'''
return self/self.length()
def normalize(self):
'''Normalize this Vec3'''
self /= self.length()

With this written as a script I imported it into IPython thusly:

from Vec3 import *

v = Vec3(3,4,5)

v.add(3)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
C:\Users\CHUCK\Documents\<ipython-input-7-4b1689e130e9> in <module>()
----> 1 v.add(3)

AttributeError: Vec3 instance has no attribute 'add'

As you can see from the code above, add is clearly an attribute of class Vec3.

So my question is how can I call the functions of my class without this error?

Am I calling the class correctly?

Any and all help is appreciated.
 
Technology news on Phys.org
The Vec3 class does not have an add function - however, it has a function named __add__

Code:
def __add__(self, other):
'''Addition, supports types Vec3 and other 
types that supports the + operator ''' 
if isinstance(other, Vec3):
return Vec3( self.x + other.x, self.y + other.y, self.z + other.z )
else: #Raise an exception if not a float or integer
return Vec3(self.x + other, self.y + other, self.z + other)
 

Similar threads

  • · Replies 19 ·
Replies
19
Views
3K
  • · Replies 2 ·
Replies
2
Views
1K
  • · Replies 2 ·
Replies
2
Views
4K
  • · Replies 2 ·
Replies
2
Views
3K
  • · Replies 5 ·
Replies
5
Views
4K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 43 ·
2
Replies
43
Views
4K
  • · Replies 1 ·
Replies
1
Views
5K
  • · Replies 3 ·
Replies
3
Views
1K