Filling a Triangle in Python - python

I have a python program where the object is to have the user enter the length of the sides of a triangle, if they would like to fill it, and what color. I keep getting an attribute error pertaining to GeometricObject and fill.
After a few fixes I am stuck in the same area again (fill), this is the error I keep getting:
> Traceback (most recent call last): File "Desktop/one.py", line 81,
> in <module>
> main() File "Desktop/one.py", line 78, in main
> "Is filled? : ", triangle.ColorFill()) File "Desktop/one.py", line 21, in ColorFill
> return self.__filled AttributeError: 'Triangle' object has no attribute '_GeometricObject__filled'
I am not sure where to untangle this, any help would be welcomed. Below is my code:
12.1 The Triangle class
import math
#class for the GeometricObject, must be defined before Trianble. includes fill
class GeometricObject:
#if true the color will be green
def __init__(self, color =" ", filled = True):
self.__color = color
self__filled = filled
#getting the fill color and setting it to green fill
def getColor(self):
return self.__color
def setColor(self, color):
self.__color = color
def ColorFill(self):
return self.__filled
def setColorFill(self, filled):
self__filled = filled
#string that tells you if it is filled or not
def __st__(self):
return "Color is: " + (self.__color) \
+ "Fill: " + str(self.__filled)
#setting class for triangle and calling on geometric objects
class Triangle(GeometricObject):
def __init__(self, side1 = 1.0, side2 = 1.0, side3 = 1.0):
self.__side1 = side1
self.__side2 = side2
self.__side3 = side3
#calling GeometricObject, this is what triangle is bound to
GeometricObject.__init__(self)
#getting length of sides
def getLengthA(self):
return side1
def getLengthB(self):
return side2
def getLengthC(self):
return side3
#setting and getting perimeter
def setPerimeter(self):
self.perimeter = perimeter
def getPerimeter(self):
perimeter = self.__side1 + self.__side2 + self.__side3
return perimeter
#setting and getting area
def setArea(self):
self.area = area
def getArea(self):
s = (self.__side1 + self.__side2 + self.__side3) / 2
area = math.sqrt(s * ((s - self.__side1) * (s - self.__side2) * (s - self.__side3)))
return area
#printing string, sides
def toString(self):
return "Triangle: Side 1: " + (self.__side1)\
+ "Side 2: " + (self.__side2)\
+ "Side 3: " + (self.__side3)
def main():
#user enters sides of a triangle
side1, side2, side3 = eval(input("Enter the length of the Tiangle's sides (A, B, C): "))
triangle = Triangle(side1, side2, side3)
#user enters color
color = input("Enter a color: ")
triangle.setColor(color)
#user enter if filled
filled = eval(input("Enter 1 to fill with color \n Enter 0 for no fill: "))
ColorFill = (filled == 1)
triangle.setColorFill(ColorFill)
print("The area of the triangle is: " , triangle.getArea(), \
"The perimeter is: " , triangle.getPerimeter(), \
"The color is: ", triangle.getColor(), \
"Is filled? : ", triangle.ColorFill())
main()

Related

How to print in Python using class and print function

class HexagonInteriorAngle(object):
def __init__(self, x):
self.x = self
def FindInteriorAngle(self):
degrees = int((x - 2) * 180)
interior = int(degrees / x)
def Print(self):
if x == 3:
print(str("an interior angle of a triangle equals " + str(interior)))
elif x == 4:
print("an interior angle of an equilateral equals " + str(interior))
elif x == 5:
print("an interior angle of a pentagon equals " + str(interior))
elif x == 6:
print("an interior angle of a hexagon equals " + str(interior))
elif x == 7:
print("an interior angle of a heptagon equals " + str(interior))
elif x == 8:
print("an interior angle of an octagon equals " + str(interior))
elif x == 9:
print("an interior angle of a nonagon equals " + str(interior))
elif x == 10:
print("an interior angle of a decagon equals " + str(interior))
else:
print(str(interior))
if __name__ == "__main__":
x = int(input("enter: "))
hexaObj = HexagonInteriorAngle(x)
hexaObj.FindInteriorAngle()
hexaObj.Print()
What I want the program to do is to identify what type of polygon it is based off of the number of sides (ex. 6 sides = hexagon, 5 sides = pentagon, etc) and then print what one interior angle would be for that polygon (formula to find the interior angle : (the number of sides - 2) x 180 and then taking that answer and then dividing it by the number of sides). example: hexagon.
( 6 - 2 ) x 180 = 720
720 / 6 = 120
Right now I'm pretty sure the actual code part is correct because if you do this it prints fine:
class HexagonInteriorAngle(object):
def __init__(self, x):
self.x = self
def FindInteriorAngle(self):
degrees = int((x - 2) * 180)
interior = int(degrees / x)
print("interior angle " + str(interior))
if __name__ == "__main__":
x = int(input("enter: "))
hexaObj = HexagonInteriorAngle(x)
hexaObj.FindInteriorAngle()
You should do this:
def FindInteriorAngle(self):
degrees = int((x - 2) * 180)
interior = int(degrees / x)
return interior
# ...
if __name__ == "__main__":
x = int(input("enter: "))
hexaObj = HexagonInteriorAngle(x)
interior = hexaObj.FindInteriorAngle()
print("interior angle " + str(interior))
Almost unrelated to your answer, we could clean up your code a bit with the use of some property fields. Using __str__ instead of a Print method is more idiomatic, as well.
class Polygon:
shapes = [
None, # index 0
None, # index 1
"line", # index 2, etc...
"triangle",
"rectangle",
"pentagon",
"hexagon",
"heptagon",
"octogon",
"nonagon",
"decagon",
]
def __init__(self, sides):
if not 2 <= sides <= 10:
raise ValueError("Polygon only supports shapes with sides 2-10")
self.sides = sides
#property
def shape(self):
return self.shapes[self.sides]
#property
def interior_angle(self):
return (self.sides - 2) * 180 / self.sides
def __str__(self):
return f"The interior angle of a {self.shape} is {self.interior_angle}"
if __name__ == "__main__":
poly = Polygon(3)
print(poly)

How to convert from metric to imperial and vise versa (bmi )?

I have to create a BMI program. The weight should be entered as kilograms and the height as cm, then the program should convert the entered values to imperial equivalents and display them and after it should then calculate the BMI and display the result.
So far I have created a BMI calculator where the user can choose between Metric and Imperial. I have created a while true statement for the user to choose only between metric and imperial and when the user puts the height and the weight it will calculate and then display the result. BUT my problem is that I have to convert the metric values to imperial and I don't know how to do it. I miss the converter for metric to imperial and vice versa, any ideas how to improve it?
while True:
try:
if choice == 'Metric':
weight = float(input('weight in kg:'))
height = float(input('height in cm:'))
if choice == 'Imperial':
weight = float(input('weight in pounds:'))
height = float(input('height in inches:'))
except ValueError:
print('Invalid input')
else:
break
if choice == "Metric":
bmi = weight / (height * height)
return bmi
if choice == "Imperial":
bmi = (weight * 703) / (height * height)
return bmi
You first have to define the variable choice because so far you have created if statements that are just not being activated. So try this:
def conversion_to_metric(weight, height):
"""Convert values from Imperial to Metric"""
pound = 0.453592
kg_ans = float(weight * pound)
inch = 2.54
cm_ans = float(inch * height)
print("--------------------")
print(str(weight) + "lbs. " + "= " + str(kg_ans) + "kg.")
print(str(height) + "in. " + "= " + str(cm_ans) + "cm.")
def conversion_to_imperial(weight, height):
"""Convert values from Metric to Imperial"""
kg = 2.20462
lbs_ans = float(weight * kg)
cm = 0.393701
inch_ans = float(cm * height)
print("--------------------")
print(str(weight) + "kg. " + "= " + str(lbs_ans) + "lbs.")
print(str(height) + "cm. " + "= " + str(inch_ans) + "in.")
while True:
try:
print("A. Imperial -> Metric\n" + "B. Metric -> Imperial")
choice = input("Choose a conversion: ")
if choice == 'B':
weight = float(input('\tweight in kg:'))
height = float(input('\theight in cm:'))
conversion_to_imperial(weight, height)
if weight == 'q' or height == 'q':
break
elif choice == 'A':
weight = float(input('\tweight in pounds:'))
height = float(input('\theight in inches:'))
conversion_to_metric(weight, height)
if weight == 'q' or height == 'q':
break
elif choice == 'q':
break
except ValueError:
print('Please enter either A or B...')
Hope this helps. Remember to always give the user an option to quit, or else you will have an endless loop that eats up your memory. Fix a few of my variable around.

Having trouble calling the parent class method from child class

I've started trying to learn Python after working with Java for the past year and decided to work on a couple class projects I've done and to write them in Python. I am getting an AttributeError at line 102, stating my super object has no attribute 'area'.
I've looked through different posts of how it's done, and I can't seem to figure out why this isn't working correctly for me after following other solutions.
It's a simple program that takes in input from the user, parses it, then depending on the shape type, will call the methods of the appropriate object type, then calculates and prints it out. For example, an input would be "R 3/4 5-7", supposed to weigh 8.37, or "P 1/4 5-6 2-3", supposed to weigh 126.07.
import math
class Shipment:
_weight = 0
def weight(self):
return self._weight
def frac_in_feet(self, frac):
thick_frac = frac.replace('/', "")
print("number is: ", thick_frac)
numerator = int(thick_frac[0])
denominator = int(thick_frac[1])
fraction_of_an_inch = numerator / denominator
return self.in_feet(0, fraction_of_an_inch)
def feet_and_inches_in_feet(self, feet_and_inches):
a = feet_and_inches.replace('-', "")
print("number is: ", a)
feet = int(a[0])
inches = int(a[1])
return self.in_feet(feet, inches)
def in_feet(self, feet, inches):
inches /= 12
print(feet + inches)
return feet + inches
def get_value_in_feet(self, str):
i = str.find('/')
j = str.find('-')
if i == -1:
value = self.feet_and_inches_in_feet(str)
if j == -1:
value = self.frac_in_feet(str)
return value
def add_item(self, quantity, description):
desc_values = description.replace(" ", "")
values = []
shape_letter = desc_values[0]
i = 1
j = 4
for r in range(int(len(desc_values) / 3)):
print("r is: ", r)
values.append(self.get_value_in_feet(desc_values[i:j]))
i += 3
j += 3
if shape_letter == 'P':
if len(values) != 3:
raise ValueError("Plate needs three dimensions. ")
shape = Plate(values[0], values[1], values[2])
elif shape_letter == 'R':
if len(values) != 2:
raise ValueError("Rod needs two dimensions")
shape = Rod(values[0], values[1])
else:
raise ValueError("Shape letter ", shape_letter, " not recognized.")
self._weight += quantity * shape.weight()
return shape
class SteelShape:
_length = 0
_weight = 0
def length(self, length):
_length = length
def length(self):
return self._length
def weight(self, weight):
self._weight = weight
def weight(self):
return self._weight
class CalcShape(SteelShape):
_area = 0
def area(self, area):
self._area = area
def weight(self):
return self._area * self.length() * 489
class Rod(CalcShape):
def __init__(self, diameter, length):
radius = diameter / 2
super(CalcShape, self).area(math.pi * radius**2)
super(CalcShape, self).length
class Plate(CalcShape):
def __init__(self, thick, width, length):
super(CalcShape, self).area(thick * width)
super(SteelShape, self).length(length)
values = []
shipment = Shipment()
shape = SteelShape()
line = input("Enter shape and dimensions: ")
shape = shipment.add_item(1, line)
if isinstance(shape, Plate):
print("Plate weighs ", shape.weight())
elif isinstance(shape, Rod):
print("Rod weighs ", shape.weight())
print("Total shipment weight: ", shipment.weight())
# R 3/4 5-7: supposed to weigh 8.37
# P 1/4 5-6 2-3: supposed to weigh 126.07
I think replacing the super and instead using staticmethod is a better choice. See here:
https://stackoverflow.com/a/735978/10416716
Hope this helps.

TypeError: unsupported operand type(s) for *: 'int' and 'function' Not seeing why and which one is a function

I can't figure out why I am getting an error with having an int and a function multiplying.
File "E:/Fundamentals of Programming/Programs/polygon_area.py", line 23, in polygon_area
area = (num_sides * side_length * side_length) / \
TypeError: unsupported operand type(s) for *: 'int' and 'function'
Code:
#this program computes
#the area of polygons
import math
def main():
get_side_length()
side_length = get_side_length
report(side_length)
def report(side_length):
print('side length \t number of sides \t area')
for i in range(3, 10):
num_sides = i
polygon_area(num_sides, side_length)
area = polygon_area
print(side_length, '\t', num_sides, '\t', area)
def polygon_area(num_sides, side_length):
area = (num_sides * side_length * side_length) / \
(4 * math.tan(math.pi / num_sides))
return area
def get_side_length():
int(input('Input the length of a side. '))
return get_side_length
#start program
main()
The way you call functions causes the issue.
side_length = get_side_length
The above code assigns side_length with the function itself. To assign side_length as the value returned by the function, use:
side_length = get_side_length()
Similiarly,
area = polygon_area(num_sides, side_length)
And get_side_length function should be:
def get_side_length():
side_length = int(input('Input the length of a side. '))
return side_length
Since side_length refers to a function in your code, you get the above error.
I'm sorry for not having read your code carefully. You may need to know that a function should return something. And in your get_side_length, for example, the result, which is an integer, should be returned.
I've changed your code, which should work now.
import math
def main():
side_length = get_side_length() # get_side_length returns an integer and assigns it to side_length
report(side_length)
def report(side_length):
print('side length \t number of sides \t area')
for i in range(3, 10):
num_sides = i
area = polygon_area(num_sides, side_length) # polygon_area returns an number representing the area and assigns it to area
print(side_length, '\t', num_sides, '\t', area)
def polygon_area(num_sides, side_length):
area = (num_sides * side_length * side_length) / \
(4 * math.tan(math.pi / num_sides))
return area
def get_side_length():
return (input('Input the length of a side. ')) # you get an integer from input and should return it

How can I get my user input to run from my class? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
bob = Turtle()
bob.shape("turtle")
class SimpleDraw(Turtle):
def __init__(Turtle):
bob = Turtle
def draw_square(bob, length):
'''This function draws a regular square'''
for i in range(4):
bob.forward(length)
bob.left(90)
def draw_polygon(bob, n, length):
'''This function draws a regular polygon'''
angle = 360.0 / n
for i in range(n):
bob.forward(length)
bob.left(angle)
def draw_circle (t, r):
circumference = 2 * math.pi * r
n = 50
length = circumference / n
polygon (t, n, length)
drawObj = SimpleDraw
drawObj.draw_polygon
drawObj.draw_circle
drawObj.draw_square
def testSimpleDraw():
number = raw_input('Please choose a draw option: \
1-draw square \
2-draw polygon \
3-draw circle \
0-to exit');
if number == 0:
exit()
else:
if number == 1:
drawObj.draw_square(bob, 5)
else:
if number == 2:
drawObj.draw_polygon(bob, 7, 70)
else:
if number == 3:
drawObj.draw_circle(50, 50)
if __name__ == '__main__':
testSimpleDraw()
drawObj = SimpleDraw needs to be changed to drawObj = SimpleDraw()
That's how you instantiate a class. You are assigning the SimpleDraw class to drawObj - drawObj is the same as SimpleDraw class not an instance of SimpleDraw in your code.
In this line:
drawObj = SimpleDraw
you assign the class SimpleDraw to the name drawObj. Instead, you should create an instance of the class to assign:
drawObj = SimpleDraw() # note parentheses
You don't need the __init__ in your SimpleDraw class; you inherit this from Turtle. It is conventional to call the first argument to instance methods self, rather than bob! For example:
def draw_square(self, length):
'''This function draws a regular square'''
for i in range(4):
self.forward(length)
self.left(90)
You will need to adjust your draw_circle method to correctly call the draw_polygon method:
def draw_circle(self, r, n=50):
circumference = 2 * math.pi * r
length = circumference / n
self.draw_polygon(n, length)
Note that you can use elif to simplify your code:
if number == 0:
...
elif number == 1:
...
I'm going to take a guess at what you're trying to do. First, lets rewrite this code and I'll explain the changes as we go along.
class SimpleDraw(Turtle):
# No __init__ need, calls __init__ of subclass implicitly
# So self refers to an instance of Turtle
# Since all your code essentially makes use of the same thing, lets create
# a generic base draw.
def draw_generic(self, angle, length, n):
for i in range(n):
self.forward(length)
self.left(angle)
def draw_square(self, length):
# Notice self instead of bob, this is how you refer to the instance
# of the class that has been created.
"""
This function draws a regular square.
"""
self.draw_generic(90, length, 4) # Note, self implicitly passed
def draw_polygon(self, n, length):
"""
This function draws a regular polygon
"""
angle = 360.0 / n
self.draw_generic(angle, length, n)
def draw_circle(self, t, r):
circumference = 2 * math.pi * r
n = 50
length = circumference / n
self.draw_polygon(t, n, length) # Note: draw_polygon instead of polygon
def test_simple_draw():
# Note the lowercase and underscores, this preferred by PEP 8
# http://stackoverflow.com/questions/8908760/should-i-use-camel-case-or-underscores-in-python
options = ["1 - draw square", "2 - draw polygon", "3 - draw circle", "0 -exit"]
msg = "Please choose a draw option:\n %s" % ("\n".join(options))
# Note that number is a string, so we have to try and coerce it to an int, and
# validate this as well.
number = None
while number is None:
try:
number = raw_input(msg)
number = int(number)
if 0 > number or 3 < number:
raise ValueError # Not a valid option
except ValueError: # If the coercion fails
print "%s is not a valid option. Please re-enter." % number
number = None # Set to None so we loop again
# Now we have the number, and it's actually a number.
# You make a lot of use of else, which can be replaced by elif, which is the
# like else but specifies a condition; a union of if and else
drawObj = SimpleDraw() # We create our object here, note braces for instantiation
if number == 0:
exit()
elif number == 1:
drawObj.draw_square(5)
elif number == 2:
drawObj.draw_polygon(7, 70)
else: # We can have confidence in this value because of our checks above
drawObj.draw_circle(50, 50)
if __name__ == "__main__":
test_simple_draw()
Now This code gets across the idea that you initially wanted, but makes use of the class inheritance that you were originally trying to use.
Further sources for reference:
Classes: http://docs.python.org/2/tutorial/classes.html
import math
import random
import turtle
class SimpleTurtle(turtle.Turtle):
# There is no need to override the default __init__
# Also, making the self argument 'bob' is just irritating -
# everyone expects to see 'self', why mess us up?
def draw_polygon(self, num_sides, side_length):
"""
Draw an n-sided regular polygon
"""
angle = 360. / num_sides
for side in range(num_sides):
self.forward(side_length)
self.left(angle)
def draw_square(self, side_length):
"""
Draw a square
"""
self.draw_polygon(4, side_length)
def draw_circle(self, radius, num_sides=60):
"""
Draw a circle
"""
angle = 360. / num_sides
side_length = 2. * radius * math.sin(math.radians(angle))
self.draw_polygon(num_sides, side_length)
def get_int(prompt, lo=None, hi=None):
while True:
try:
val = int(raw_input(prompt))
if (lo is None or lo <= val) and (hi is None or val <= hi):
return val
except ValueError:
pass
def do_menu(prompt, options):
print(prompt)
for i,opt in enumerate(options, 1):
print(" {:>2}: {}".format(i, opt))
return get_int("? ", 1, len(options)) - 1
def test_SimpleTurtle():
bob = SimpleTurtle(shape="turtle")
while True:
choice = do_menu("Please choose a draw option:", ["draw a square", "draw a polygon", "draw a circle", "quit"])
if choice == 0:
side_length = random.randint(10, 50)
bob.draw_square(side_length)
elif choice == 1:
sides = random.randint(5, 12)
side_length = random.randint(6, 30)
bob.draw_polygon(sides, side_length)
elif choice == 2:
radius = random.randint(8, 40)
bob.draw_circle(radius)
else:
break
if __name__ == '__main__':
test_SimpleTurtle()

Categories