kathy
kathy

Reputation: 21

Typeerror: unsupported operand type(s) for /: 'Decimal' and 'float'

Here is my code: I have tried all day to solve the mistake but I still have the error:

TypeError: unsupported operand type(s) for /: 'Decimal' and 'float'.

from math import sqrt, acos, pi

from decimal import Decimal, getcontext

getcontext().prec = 30

class Vector(object):

    CANNOT_NORMALIZE_ZERO_VECTOR_MSG = 'Cannot compute an angle with the zero vector'

    def __init__(self, coordinates):
        try:
            if not coordinates:
                raise ValueError
            self.coordinates = tuple(Decimal(x) for x in coordinates)
            self.dimension = len(self.coordinates)

        except ValueError:
            raise ValueError('The coordinates must be nonempty')

        except TypeError:
            raise TypeError('The coordinates must be an iterable')
    #orthogonal or parallel
    def is_zero(self, tolerance=1e-10):
        return self.magnitude() < tolerance

    def is_orthogonal_to(self, v, tolerance=1e-10):
        return abs(self.dot(v)) < tolerance

    def is_parallel_to(self, v):
        return ( self.is_zero() or 
                v.is_zero() or
                self.angle_with(v) == 0 or
                self.angle_with(v) == pi )

    #dot product &angle
    def dot(self, v):
        return sum([x*y for x,y in zip(self.coordinates,v.coordinates)])
    def angle_with(self,v,in_degrees=False):
        try:
            u1 = self.normalized()
            u2 = v.normalized()
            angle_in_radians = acos(u1.dot(u2))

            if in_degrees:
                degrees_per_radian = 180./pi
                return angle_in_radians * degrees_per_radian
            else:
                return angle_in_radians

        except Exception as e:
            if str(e) == self.CANNOT_NORMALIZE_ZERO_VECTOR_MSG:
                raise Exception('Cannot compute an angle with the zero vector')
            else:
                raise e


    #magnitude& Direction
    def magnitude(self):
        coordinates_squared = [x**2 for x in self.coordinates]
        return sqrt(sum(coordinates_squared))
    def normalized(self):
        try:
            magnitude = self.magnitude()
            return self.times_scalar(Decimal('1.0')/magnitude)
        except ZeroDivisionError:
            raise Exception(self.CANNOT_NORMALIZE_ZERO_VECTOR_MSG)
    #Plus,minus, scalar multiply
    def plus(self, v):
        new_coordinates = [x+y for x,y in zip(self.coordinates,v.coordinates)]
        return Vector(new_coordinates)
    def minus(self, v):
        new_coordinates = [x-y for x,y in zip(self.coordinates,v.coordinates)]
        return Vector(new_coordinates)
    def times_scalar(self, c):
        new_coordinates = [Decimal(c)*x for x in self.coordinates]
        return Vector(new_coordinates)

    def __str__(self):
        return 'Vector: {}'.format(self.coordinates)

    def __eq__(self, v):
        return self.coordinates == v.coordinates

v = Vector(['8','-9'])

w = Vector(['-1','-1'])

print v.dot(w)

print v.angle_with(w)

print v.angle_with(w, in_degrees=True)

Upvotes: 2

Views: 2966

Answers (1)

Stephen Rauch
Stephen Rauch

Reputation: 49784

In general it usually does not make sense to mix Decimal and float math. Not sure why you need Decimal here, but with two small changes this code can be made to run. I would suggest considering getting rid of the Decimal unless you are sure you need it:

Change magnitude to:

# magnitude& Direction
def magnitude(self):
    coordinates_squared = [x ** 2 for x in self.coordinates]
    return sum(coordinates_squared) ** Decimal('0.5')

And the acos call to:

angle_in_radians = Decimal(str(acos(u1.dot(u2))))

Upvotes: 2

Related Questions