This is a program I am working on for homework and I keep getting this error and I'm not sure what I can do to fix it. Any help would be greatly appreciated.

here is the error:

Traceback (most recent call last):
  File "C:\Users\crazyjdog\Desktop\School Stuff\CSET 1100\Programs and Charts\program121.py", line 86, in <module>
    main()
  File "C:\Users\crazyjdog\Desktop\School Stuff\CSET 1100\Programs and Charts\program121.py", line 80, in main
    tri.setArea(side1, side2, side3)
  File "C:\Users\crazyjdog\Desktop\School Stuff\CSET 1100\Programs and Charts\program121.py", line 56, in setArea
    area = sqrt(s(s-side1)(s-side2)(s-side3))
TypeError: 'float' object is not callable

this is the code for the program:

from math import *
class GeometricObject():
    def __init__(self, color = "green", filled = True):
        self.__color = color
        self.__filled = filled

        def getColor(self):
            return self.__color

        def setColor(self, color):
            self.__color = color

        def isFilled(self):
            return self.__filled

        def setFilled(self, filled):
            self.__filled = filled

        def __str__(self):
            return "color: " + self.__color + \
                   " and filled: " + str(self.__filled)


class Triangle(GeometricObject):
    def __init__(self, side1 = 1, side2 = 1, side3 = 1):
        super().__init__()
        self.__side1 = float(side1)
        self.__side2 = float(side2)
        self.__side3 = float(side3)

    def getSide1(self):
        return self.__side1

    def setSide1(self, side1):
        self.__side1 = side1

    def getSide2(self):
        return self.__side2

    def setSide2(self, side2):
        self.__side2 = side2

    def getSide3(self):
        return self.__side3

    def setSide3(self, side3):
        self.__side3 = side3

    def getArea(self):
        return self.__area

    def setArea(self, side1, side2, side3):
        s = (side1 + side2 + side3)/2
        area = sqrt(s(s-side1)(s-side2)(s-side3))
        self.__area = area

    def getPerimeter(self):
        return self.__perimeter

    def setPerimeter(side1, side2, side3):
        perimeter = side1 + side2 + side3
        self.__perimeter = perimeter

    def __str__(self):
        return "Triangle: " + "side 1 = " + str(self.__side1)+ " " +\
                "side 2 = " + str(self.__side2) + " " + \
                "side 3 = " + str(self.__side3)

def main():
    side1 = eval(input("Enter a value for side 1: "))
    side2 = eval(input("Now enter a value for side 2: "))
    side3 = eval(input("Now enter a value for side 3: "))
    color = input("Enter the color of the triangle: ")
    filled = input("Enter 1(filled) or 0(not filled) " + \
                   " for the triangle being filled: ")

    tri = Triangle(side1, side2, side3)
    print("\n\n")
    print("A Triangle ", tri.__str__())
    print("The area is: ", tri.getArea())
    print("The perimeter is: ", tri.getPerimeter())

main()

Recommended Answers

All 13 Replies

python uses (* asterix) for multiplication. in line 54 it assumes the s(s-side1) as a function call not a multiplication.
it should look like

s*(s-side1)*(s-side2)...

Okay, I made the change and now I got this error. I have been working on this program just about all day and I have no idea what is causing these errors, with some minor changes I could get this same program to work just fine in C# or java.

Traceback (most recent call last):
  File "C:\Users\crazyjdog\Desktop\School Stuff\CSET 1100\Programs and Charts\program121.py", line 85, in <module>
    main()
  File "C:\Users\crazyjdog\Desktop\School Stuff\CSET 1100\Programs and Charts\program121.py", line 82, in main
    print("The area is: ", tri.getArea())
  File "C:\Users\crazyjdog\Desktop\School Stuff\CSET 1100\Programs and Charts\program121.py", line 52, in getArea
    return self.__area
AttributeError: 'Triangle' object has no attribute '_Triangle__area'

The error you're getting is because your setArea function has not been called before the getArea function is called. setArea is where self.__area is first declared/initialised.

So as your code stands, as far as the python interpreter can see, your class does not have a property called __area

Personally I'd scrap the setArea and setPerimeter functions and create a class function called recalulate instead which will calculate __area and __perimeter:

def recalculate(self):
    self.__perimeter = self.__side1 + self.__side2 + self.__side3
    s = (self.__side1 + self.__side2 + self.__side3)/2
    self.__area = sqrt(s*(s-self.__side1)*(s-self.__side2)*(s-self.__side3))

Then call self.recalculate at the end of your class constructor.
You might also want to call self.recalculate at the end of the three setSide functions to recalculate the area and perimeter of the triangle when one of the sides has changed.

I think you have teacher with java background.

There are really no need for getters/setters in both of these Class.
Java programmers will often introduce private members, and then add getters and setters.
This is evil; the attribute should have been public in the first place.

Something to read Python is not Java

Getters and setters are evil. Evil, evil, I say! Python objects are not Java beans. Do not write getters and setters. This is what the 'property' built-in is for. And do not take that to mean that you should write getters and setters, and then wrap them in 'property'. That means that until you prove that you need anything more than a simple attribute access, don't write getters and setters. They are a waste of CPU time, but more important, they are a waste of programmer time. Not just for the people writing the code and tests, but for the people who have to read and understand them as well.

Just a demo with GeometricObject class.
Use it:

>>> c = GeometricObject('Yellow', False)
>>> c._GeometricObject__color
'Yellow'
>>> c._GeometricObject__filled
False
>>> c._GeometricObject__color = 'Black'
>>> c._GeometricObject__filled = True
>>> c._GeometricObject__color
'Black'
>>> c._GeometricObject__filled
True

Rewrite it.

class GeometricObject():
    def __init__(self, color = "green", filled = True):
        self.color = color
        self.filled = filled

        def __str__(self):
            return 'Color {} and filled {}'.format(self.color, self.filled)

Use it:

>>> c = GeometricObject('Yellow', False)
>>> c.color
'Yellow'
>>> c.filled
False
>>> c.color = 'Black'
>>> c.filled = True
>>> c.color
'Black'
>>> c.filled
True

As you se a can do same stuff and clearer with less code.

Actually, I have a C# background and the book is written to be a step into Java. Also, the exercise specifically asks for methods getArea() and getPerimeter(). I do see what you mean about not needing all of the getters and setters problem is I have to use the geometricObject class as is because that is what the book wants to be used as a base class. I do think that with your sugestions I can figure out what I need to do.

JasonHippy has give advice of why you get that error and how to fix it.
If you scrap the setArea and setPerimeter method and use recalculate it look like this.

>>> tri = Triangle(side1, side2, side3)
>>> tri.recalculate()
>>> tri.getArea()
11.61895003862225
>>> tri.getPerimeter()
18.0
>>> tri._GeometricObject__color
'green'

So a rewrite to get the same.

from math import *

class GeometricObject():
    def __init__(self, color = "green", filled = True):
        self.color = color
        self.filled = filled

class Triangle(GeometricObject):
    def __init__(self, side1=1, side2=1, side3=1):
        super().__init__()
        self.side1 = float(side1)
        self.side2 = float(side2)
        self.side3 = float(side3)

    def calulate(self):
        self.perimeter = self.side1 + self.side2 + self.side3
        s = (self.side1 + self.side2 + self.side3) / 2
        self.area = sqrt(s* (s-self.side1) * (s-self.side2) * (s-self.side3))

    '''
    side1 = 8
    side2 = 4
    side3 = 6
    color = 'Yellow'
    filled = 1
    '''

Use it:

>>> tri = Triangle(side1, side2, side3)
>>> tri.calulate()
>>> tri.area
11.61895003862225
>>> tri.perimeter
18.0
>>> tri.color
'green'

Do not use use eval
side1 = int(input("Enter a value for side 1: "))

Actually, I have a C# background and the book is written to be a step into Java

Please do not try to learn any programming language by leveraging knowledge of another programming language.
Programming languages (with a few exceptions) are more different than alike.
It's much easier on your brain to start "from scratch" when learning a new language.
Try to avoid comparing syntax or semantics between languages.

I got most of everything to work, now I am stuck on getting the color and filled properties to show up

this is the display I get

A Triangle:  Triangle: side 1 = 3.0 side 2 = 4.0 side 3 = 5.0 <__main__.GeometricObject object at 0x00000000031BFE48>
The area is:  6.0
The perimeter is:  12

using this code with the above class for Triangle and GeometricObject from snippsat. If I use the get and set for for color and filled I get a traceback error that says GeometricObject has no attribute setColor. What can I do to get the color and filled properties to display?

    side1 = eval(input("Enter a value for side 1: "))
    side2 = eval(input("Now enter a value for side 2: "))
    side3 = eval(input("Now enter a value for side 3: "))
    color = input("Enter the color of the triangle: ")
    filled = input("Enter 1(filled) or 0(not filled) " + \
                   "for the triangle being filled: ")

    gO = GeometricObject(color, filled)
    tri = Triangle(side1, side2, side3)
    tri.setArea(side1, side2, side3)
    tri.setPerimeter(side1, side2, side3)

    print("\n\n")
    print("A Triangle: ", tri.__str__(), gO)
    print("The area is: ", tri.getArea())
    print("The perimeter is: ", tri.getPerimeter())

using this code with the above class for Triangle and GeometricObject from snippsat. If I use the get and set for for color and filled I get a traceback error that says GeometricObject has no attribute setColor. What can I do to get the color and filled properties to display?

If you are gone use my class you can of course not use old method name from your class.
So if i also put in __str__ method it can look like this.

from math import sqrt

class GeometricObject:
    def __init__(self, color="green", filled=True):
        self.color = color
        self.filled = filled

    def __str__(self):
        return 'Color {} and filled {}'.format(self.color, self.filled)    

class Triangle(GeometricObject):
    def __init__(self, side1=1, side2=1, side3=1):
        super().__init__()
        self.side1 = float(side1)
        self.side2 = float(side2)
        self.side3 = float(side3)

    def calulate(self):
        self.perimeter = self.side1 + self.side2 + self.side3
        s = (self.side1 + self.side2 + self.side3) / 2
        self.area = sqrt(s* (s-self.side1) * (s-self.side2) * (s-self.side3))

    def __str__(self):
        return "Triangle:\nside 1 = {}\n"\
                         "side 2 = {}\n"\
                         "side 3 = {}".format(self.side1,self.side2,self.side3)

# User input
side1 = 3.0
side2 = 4.0
side3 = 5.0
color = 'Yellow'
filled = 1 

Use it:

>>> go = GeometricObject(color, filled)
>>> tri = Triangle(side1, side2, side3)
>>> print('{}\n{}'.format(tri, go))    
Triangle:
side 1 = 3.5
side 2 = 4.0
side 3 = 5.0
Color Yellow and filled 1

>>> tri.calulate()
>>> print("The area is: ", tri.area)
The area is:  6.0

>>> print("The perimeter is: ", tri.perimeter)
The perimeter is:  12.0

>>> tri.side1
3.0    
>>> tri.side1 = 3.5

>>> tri.calulate()    
>>> print("The area is: ", tri.area)
The area is:  6.952686081652184

>>> print("The perimeter is: ", tri.perimeter)
The perimeter is:  12.5

I'm kind of confused by your post, this is what I have for my code:

from math import *
class GeometricObject():
    def __init__(self, color = "green", filled = True):
        self.color = color
        self.filled = filled

        def getColor(self):
            return self.color

        def setColor(self, color):
            self.color = color

        def getFilled(self):
            return self.filled

        def setFilled(self, filled):
            if filled == "1":
                filled = True
            if filled == "0":
                filled = False

            self.filled = filled

        def __str__(self):
            return "color: " + self.__color + \
                   " and filled: " + str(self.__filled)


class Triangle(GeometricObject):
    def __init__(self, side1 = 1, side2 = 1, side3 = 1):
        super().__init__()
        self.side1 = float(side1)
        self.side2 = float(side2)
        self.side3 = float(side3)

    def getArea(self):
        return self.area

    def setArea(self, side1, side2, side3):
        s = (side1 + side2 + side3)/2
        area = sqrt(s*(s-side1)*(s-side2)*(s-side3))
        self.area = area

    def getPerimeter(self):
        return self.perimeter

    def setPerimeter(self, side1, side2, side3):
        perimeter = side1 + side2 + side3
        self.perimeter = perimeter

    def __str__(self):
        return "Triangle: " + "side 1 = " + str(self.side1)+ \
               " " + "side 2 = " + str(self.side2) + " " + \
                "side 3 = " + str(self.side3)

def main():
    side1 = eval(input("Enter a value for side 1: "))
    side2 = eval(input("Now enter a value for side 2: "))
    side3 = eval(input("Now enter a value for side 3: "))
    color = input("Enter the color of the triangle: ")
    filled = input("Enter 1(filled) or 0(not filled) " + \
                   "for the triangle being filled: ")

    tri = Triangle(side1, side2, side3)
    tri.setArea(side1, side2, side3)
    tri.setPerimeter(side1, side2, side3)

    print("\n\n")
    print("A Triangle: ", tri.__str__())
    print("The area is: ", tri.getArea())
    print("The perimeter is: ", tri.getPerimeter())

main()

I left the area and perimeter methods in because that is what the assignment says to have, also I tried a few things to get the color and filled property to show up but I either get a callback error or this:
<main.GeometricObject object at 0x00000000031BFE48>

I really don't know what I can do, the book is not very helpful and most of what I have is either from here or what I translated from C#(I know from scratch). Any suggestions on what I can do from here would be great.

it seems that you didnt get what snippsat pointed out.
there is no get/set method in his code. so you can't call them .

I have the area and perimeter methods in my code because the book wants them there (and I'm graded on if I do what the book asks) the only problem I have is getting the color and filled property to display. Also, I did take the get/set out of the GeometricObject class and I still get this as my output. The problem is not in the Triangle class, it's either in GeometricObject or in my call to get the values to display.
Again, I get the right perimeter and area but no color or filled property in my output.

def main():
    side1 = eval(input("Enter a value for side 1: "))
    side2 = eval(input("Now enter a value for side 2: "))
    side3 = eval(input("Now enter a value for side 3: "))
    color = input("Enter the color of the triangle: ")
    filled = input("Enter 1(filled) or 0(not filled) " + \
                   "for the triangle being filled: ")
    go = GeometricObject(color, filled)
    tri = Triangle(side1, side2, side3)
    tri.setArea(side1, side2, side3)
    tri.setPerimeter(side1, side2, side3)

    print("\n\n")
    print("A Triangle: ", tri.__str__(), go.__str__())
    print("The area is: ", tri.getArea())
    print("The perimeter is: ", tri.getPerimeter())

output:

Enter a value for side 1: 3
Now enter a value for side 2: 4
Now enter a value for side 3: 5
Enter the color of the triangle: blue
Enter 1(filled) or 0(not filled) for the triangle being filled: 1



A Triangle:  Triangle: side 1 = 3.0 side 2 = 4.0 side 3 = 5.0 <__main__.GeometricObject object at 0x000000000307EA20>
The area is:  6.0
The perimeter is:  12

If you want to use getter/setter you follow advice from JasonHippy,i have tested it and it's works.
If you wanne use my code is complete in my last post.
Dont mix stuff together.

the book wants them there (and I'm graded on if I do what the book asks)

If you want to learn python you can burn that book,and get a book that learn you python in a correct manner
and not mixing in stuff from other languages that dos not make any sense in python.

@crazyjdog: Another thing I can see that is wrong with your code is the extra instance of GeometricObject you're creating in your main() function. You don't need to do this. You have already declared the Triangle class to be derived from GeometricObject, so why not just use those GeometricObject class properties in your triangle class?

You can do this by altering the __init__ function for your Triangle class to take color and filled as additional parameters, then pass color and filled to the superclasses __init__ function. That will correctly initialise the base-class part of a Triangle instance
e.g.

def __init__(self, side1 = 1, side2 = 1, side3 = 1, color="Green", filled=True):
    super().__init__(color, filled)
    self.side1 = float(side1)
    self.side2 = float(side2)
    self.side3 = float(side3)

Then in your Triangle classes __str__() function, wherever you want to output the properties of the GeometricObject base of a triangle you simply call:
super().__str__()

e.g. in the Triangle classes __str__() function:

def __str__(self):        
    return  "Triangle: side1 = {!s}, side2 = {!s}, side3 = {!s}, {!s}".format(self.__side1, self.__side2, self.__side3, super().__str__())

Note: I've used str.format() because I think it looks a little nicer than the "foo = " + __foo + ", bar = " + __bar style of string building.

Also note: When the super().__str__() function is called, you will end up with a malformed string because the value you get for the filled variable in main() is not a bool. Therefore the value of __filled inside the class is also not strictly boolean. And this causes problems when trying to output the value of the __filled member variable as a string, resulting in a malformed string. And this has a knock-on effect on the string returned by the __str___() function in the Triangle class using the above code.

The easiest way to fix this problem is to properly set up a bool value to pass into the Triangle class constructor/__init__ function.
e.g. in your main() function one way would be something like this:

    # Get filled as a number rather than a string
    filled = eval(input("Enter 1(filled) or 0(not filled) " + \
    " for the triangle being filled: "))

    # Note: You haven't done any range checking on the users input, 
    # so we'll assume that ANY non-zero value is True

    # The boolean expression passed as the final parameter to Triangle does this:
    # If filled==0, False is passed in, else True is passed!
    tri = Triangle(side1, side2, side3, color, bool(filled!=0))

Once you've done that, the call to super().__str__() will no longer malform the string it returns when it attempts to convert the value of __filled from bool to string.

Hope this is of some help!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.