I have been creating a program to calculate a bunch of geometric shapes and I got this error while running the code bellow it:
def surface_area(self):
^
SyntaxError: invalid syntax
here is the code:
class Cylinder():
def __init__(self, radius, height):
self.radius = radius
self.height = height
def volume(self):
return pi * (self.radius ** 2) * self.height
def diameter(self):
volume = pi * (self.radius ** 2) * self.height
return 2 * sqrt(self.volume / (pi * self.height)
def surface_area(self):
return (2 * pi * self.radius * self.height) + (2 * pi * (self.radius ** 2))
def base_area(self):
return pi * self.radius ** 2
def lateral_surface_area(self):
return 2 * pi * self.radius * self.height
if someone can help that will be amazing.
There are a missing bracket in your code
def diameter(self):
volume = pi * (self.radius ** 2) * self.height
return 2 * sqrt(self.volume / (pi * self.height)
# ^ ^ ^ ^
# | open 2 close 2 |
# open open never closed
This is a simple mistake, in your diameter function the last line is missing a bracket, see return 2 * sqrt(self.volume / (pi * self.height), should be this return 2 * sqrt(self.volume / (pi * self.height)).
Notice the second bracket at the end.
You forgot a closing bracket here at line 11
return 2 * sqrt(self.volume / (pi * self.height)
class cylinder:
pi = 3.14
def __init__(self, height, radius):
self.radius = radius
self.height = height
def volume(self):
volume = self.height*3.14*self.radius**2
print('Volume of the cylinder is {}'. format(volume))
def surface_area(self):
area = 2*3.14*(self.radius)*(self.height)
print('Surface area of the cylinder is {}'. format(area))
c = cylinder(2,3)
c.surface_area()
I'm new baby in Python and having the following error can you guys look into it........................................
AttributeError: 'area' object has no attribute 'radius'. So, I'm facing error in any cases. Thank for help
import math, random
class area:
def __init__(self, radius, length, breath, height, base):
if radius == 0 and breath != 0:
self.radius = random.uniform(1.1, 9.5)
self.length = random.uniform(10.5, 15.5)
self.breath = random.uniform(15, 20)
self.height = random.uniform(20, 25)
self.base = random.uniform(26, 32)
elif length == 0 and heigh != 0:
self.radius = random.uniform(1.1, 9.5)
self.length = length
self.breath = random.uniform(15, 20)
self.height = height
self.base = base
elif height == 0 and base != 0:
self.radius = radius
self.length = random.uniform(1.1, 9.5)
self.breath = breath
self.height = random.uniform(1.1, 9.5)
self.base = base
def areaofcircle(self):
return (self.radius ** 2) * math.pi
def areaoftriangl(self):
return 0.5 * (self.height) * (self.base)
def areaofrectangle(self):
return (self.length) * (self.breath)
areas = []
for i in range(0, 10):
v = area(1, 3, 5, 0, 0)
areas.append(v)
for v in areas:
print(
"Area of Circle:",
v.areaofcircle(),
"Area of Triangle:",
v.areaoftriangl(),
"Area of Rectangle:",
v.areaofrectangle(),
)
You may need to remove radius from this function arguments
def areaofcircle(self, radius):
return (self.radius ** 2) * math.pi
to be:
def areaofcircle(self):
return (self.radius ** 2) * math.pi
By defining the function as
def areaofcircle(self, radius)
Your function expect two inputs, but in your case you only give one. As far as I understand 'radius' is a datafield of the area class. Therefore, you can call it with "self.radius". In this case if you remove the radius parameter from the function, it should all work out.
def areaofcircle(self)
Task is to find the area and volume of the shapes. Consider the following shapes while designing the code: Sphere and Cylinder.
The class should have only one constructor. Also we should create a class called as Shape
Below is code i wrote and returning outputs, but how to use new class for shapes and inherit into test or the other way.
import math
#class Shapes
class Test:
def __init__(self, *args):
self.radius = args[0]
if (len(args) == 2):
self.height = args[1]
self.area = 0
self.volume = 0
return super().__init__()
def Area(self,val):
radius = self.radius
if (val == "Sphere"):
area = 4 * 3.14 * radius ** 2
elif (val =="Cylinder"):
height = self.height
area = ((2 * 3.14 * radius) * (radius + height))
else:
area = 0
return area
def Volume(self,val):
radius = self.radius
if (val == "Sphere"):
volume = (4/3) * (3.14 * radius ** 2)
elif (val == "Cylinder"):
height = self.height
volume = 3.14 * radius * radius * height
else:
volume = 0
return volume
def main():
cylinder=Test(2,4)
print('Cylinder area:',cylinder.Area(enter code here'Cylinder'))
print('Cylinder volume:',cylinder.Volume('Cylinder'))
sphere=Test(3)
print('Sphere area:',sphere.Area('Sphere'))
print('Sphere volume:',sphere.Volume('Sphere'))
if __name__=='__main__':
main()
as specified in the question:
Create a class Shape.
Derive a class Sphere and a class Cylinder from this class Shape.
Implement the calculation of volume and area for each shape.
Then, in order to use the shapes,
You need to first create a shape.
Then call the methods get_surface, or get_volume, on the shapes created. You do this with "dot" notation
The example here under does that.
import math
class Shape:
"""abstract class for shapes"""
def __init__(self, radius):
self.radius = radius
def get_surface(self):
raise NotImplementedError
def get_volume(self):
raise NotImplementedError
class Sphere(Shape): # <-- inherits from Shape
def __init__(self, radius):
Shape.__init__(self, radius) # <-- can also use super().__init__(radius)
def get_surface(self):
return 4 * math.pi * self.radius**2 # <-- use math.pi constant i/o hard coding the value of pi
def get_volume(self):
return math.pi * self.radius**3 * 4/3
class Cylinder(Shape): # <-- inherits from Shape
def __init__(self, radius, height):
Shape.__init__(self, radius) # <-- can also use super().__init__(radius)
self.height = height
def get_surface(self):
return 2 * math.pi * self.radius * self.height + 2 * math.pi * self.radius**2
def get_volume(self):
return math.pi * self.radius**2 * self.height
def main():
cyl = Cylinder(2, 4)
print('Cylinder area:', cyl.get_surface()) # <-- call the methods on the object
print('Cylinder volume:', cyl.get_volume())
sph = Sphere(5)
print('Sphere area:',sph.get_surface())
print('Sphere volume:',sph.get_volume())
if __name__=='__main__':
main()
output:
Cylinder area: 75.3982236862
Cylinder volume: 50.2654824574
Sphere area: 314.159265359
Sphere volume: 523.598775598
The problem I have is trying to make my shape files have random locations and size, without having to put the definitions in a for loop. Here are my classes.
# Module imports
import math
import turtle as t
# Class Definitions
class Circle:
def __init__(self,x=0,y=0,r=0):
self.center = Point(x,y)
self.radius = r
def circumference(self):
result = (self.radius * 2) * math.pi
return result
def area(self):
result = (self.radius ** 2) * math.pi
return result
def draw(self,fill_color,pen_color,pen_width):
t.color(pen_color)
t.fillcolor(fill_color)
t.pensize(pen_width)
t.penup()
t.goto(self.center.x,self.center.y)
t.pendown()
t.begin_fill()
t.circle(self.radius)
t.end_fill()
t.penup()
class Point:
"""Represents a point with an x and y coordinate"""
def __init__(self, x=0, y=0):
self.x = x
self.y = y
def show(self):
print "(%d, %d)" % (self.x, self.y)
def move_to(self,x,y):
self.x = x
self.y = y
def distance(self,p):
dx = self.x - p.x
dy = self.y - p.y
dist = math.sqrt(dx**2 + dy**2)
return dist
class Rectangle:
"represented with upper left corner as a Point, width, height"""
def __init__(self,x=0,y=0,width=100,height=100):
self.corner = Point(x,y)
self.width = width
self.height = height
def go_to(self,x,y):
self.corner.move_to(x,y)
def area(self):
result = self.width * self.height
return result
def perimeter(self):
result = 2*self.width + 2*self.height
return result
def draw(self,fill_color,pen_color,pen_width):
t.color(pen_color)
t.fillcolor(fill_color)
t.pensize(pen_width)
t.penup()
t.goto(self.corner.x,self.corner.y)
t.pendown()
t.begin_fill()
t.goto(self.corner.x + self.width,self.corner.y)
t.goto(self.corner.x + self.width,self.corner.y - self.height)
t.goto(self.corner.x,self.corner.y - self.height)
t.goto(self.corner.x,self.corner.y)
t.end_fill()
t.penup()
class Segment:
def __init__(self,x1=0,y1=0,x2=100,y2=0):
self.start = Point(x1,y1)
self.end = Point(x2,y2)
def length(self):
return self.start.distance(self.end)
def draw(self,pen_color,pen_width):
t.color(pen_color)
t.pensize(pen_width)
t.penup()
t.goto(self.start.x,self.start.y)
t.pendown()
t.goto(self.end.x,self.end.y)
t.penup()
class Triangle:
def __init__(self,x1=0,y1=0,x2=0,y2=0,x3=0,y3=0):
self.start = Point(x1,y1)
self.second = Point(x2,y2)
self.third = Point(x3,y3)
self.segmentf = Segment(x1,y1,x2,y2)
self.segments = Segment(x2,y2,x3,y3)
self.segmentt = Segment(x3,y3,x1,y1)
def area(self):
a = self.segmentf.length()
b = self.segments.length()
c = self.segmentt.length()
s = (a + b + c) / 2
result = (s*(s-a)*(s-b)*(s-c)) ** 0.5
return result
def perimeter(self):
a = self.segmentf.length()
b = self.segments.length()
c = self.segmentt.length()
result = a + b + c
return result
def draw(self,fill_color,pen_color,pen_width):
t.color(pen_color)
t.fillcolor(fill_color)
t.pensize(pen_width)
t.penup()
t.goto(self.start.x,self.start.y)
t.pendown()
t.begin_fill()
t.goto(self.second.x,self.second.y)
t.goto(self.third.x,self.third.y)
t.goto(self.start.x,self.start.y)
t.end_fill()
t.penup()
And here is my main function:
# Module imports
import math
import turtle
import random
from Suter_Andrew_shapesfinal import *
# Globals
MAX_S = 50
# List Definitions
r = Rectangle(random.randint(-100,100),random.randint(-100,100),random.randint(0,100),random.randint(0,100))
t = Triangle(random.randint(-100,100),random.randint(-100,100),random.randint(-100,100),random.randint(-100,100),random.randint(-100,100),random.randint(-100,100))
c = Circle(random.randint(-100,100),random.randint(-100,100),random.randint(0,100))
shapes = [r,t,c]
colors = ["blue","green","red","purple","pink","yellow","orange","black","white"]
# Main body
for i in range(MAX_S):
s_choice = random.choice(shapes)
c_choice = random.choice(colors)
if s_choice == r:
r.draw(c_choice,c_choice,random.randint(0,10))
elif s_choice == t:
t.draw(c_choice,c_choice,random.randint(0,10))
elif s_choice == c:
c.draw(c_choice,c_choice,random.randint(0,10))
turtle.mainloop()
The function works fine, but the problem is the definitions at the top. Thanks for reading!
If you want to have random definition of a shape for each time through the loop, you're going to have to put the instantiation of it inside the for loop. There's no way around this. If you create the instantiation outside the loop, then there'll only be one and you'll end up reusing the same one in all cases (as you've seen).
# Module imports
import math
import turtle
import random
from Suter_Andrew_shapesfinal import *
randint = random.randint
# Globals
MAX_S = 50
# List Definitions
shapes = [Rectangle, Triangle, Circle]
colors = ["blue", "green", "red", "purple", "pink", "yellow", "orange", "black", "white"]
# Main body
for i in range(MAX_S):
s_choice = random.choice(shapes)
c_choice = random.choice(colors)
if s_choice == Rectangle:
r = Rectangle(*([randint(-100, 100) for x in range(2)] + [randint(0, 100) for x in range(2)]))
r.draw(c_choice, c_choice, random.randint(0, 10))
elif s_choice == Triangle:
t = Triangle(*[randint(-100, 100) for x in range(6)])
t.draw(c_choice, c_choice, random.randint(0, 10))
elif s_choice == Circle:
c = Circle(*([randint(-100, 100) for x in range(2)] + [randint(0, 100)]))
c.draw(c_choice, c_choice, random.randint(0, 10))
turtle.mainloop()
I've also simplified the arguments bit of this a bit using list comprehension to generate a list of random.randints and then using the * in front of a list when passing it to a function unpacks the list into each parameter automatically.
I am having trouble with circle to circle collision resolution.
First, i detect the collision, then if the balls collide, i separate them by the sum of their radii and set the velocities. That's easy.
My problem is when gravity is acting and a ball collides with another ball from above. It's suposed to bouce off but instead it slides very slowly until it drops in the ground.
Whats hapning is that afer the colision resolution, gravity pushes the ball down and causes another colision. I've tried separating the ball by the sum of their radii + x but it just slides a little faster.
You can watch the video at http://www.youtube.com/watch?v=tk7qQ9KDFp0&feature=youtu.be.
And here's the code that hadles colision:
for p in world.particle_list:
if not p == self:
if self.pos.sub(p.pos).get_length() <= self.radius * ppm + p.radius * ppm:
p_mass_ratio = float(self.mass) / (self.mass + p.mass)
self_mass_ratio = float(p.mass) / (self.mass + p.mass)
rel_pos = p.pos.sub(self.pos)
shift = rel_pos.set_length(- rel_pos.get_length() + self.radius * ppm + p.radius * ppm)
p.pos = p.pos.add(shift.scale(0.50))
self.pos = self.pos.add(shift.scale(-0.50))
p_speed = p.speed
self_speed = self.speed
self.speed = p_speed.add(self.speed.norm_reflect(rel_pos.set_angle(rel_pos.get_angle() + 90).scale(-self.friction))).scale(0.50 * self_mass_ratio)
p.speed = self_speed.add(p.speed.norm_reflect(rel_pos.set_angle(rel_pos.get_angle() + 90).scale(self.friction))).scale(0.50 * p_mass_ratio)
I made a vector class to handle this:
def dcos(x):
return cos(radians(x))
def dsin(x):
return sin(radians(x))
def dtan(x):
return tan(radians(x))
class Vec(object):
def __init__(self, x, y):
self.x = float(x)
self.y = float(y)
self.length = self.get_length()
self.angle = self.get_angle()
def get_length(self):
return sqrt(self.x ** 2 + self.y ** 2)
def get_angle(self):
return atan2(self.y, self.x) * 180 / pi
def add(self, vec1):
new_x = self.x + vec1.x
new_y = self.y + vec1.y
return Vec(new_x, new_y)
def sub(self, vec1):
new_x = self.x - vec1.x
new_y = self.y - vec1.y
return Vec(new_x, new_y)
def scale(self, k):
return Vec(self.x * k, self.y * k)
def set_angle(self, a):
new_x = self.length * dcos(a)
new_y = self.length * dsin(a)
if a == -90 or a == 90:
new_x = 0
if a == 180 or a == 0 or a == -180:
new_y = 0
return Vec(new_x, new_y)
def set_length(self, l):
new_x = l * dcos(self.angle)
new_y = l * dsin(self.angle)
return Vec(new_x, new_y)
def inverse(self):
return Vec(- self.x, - self.y)
def norm_reflect(self, vec1):
if self.get_angle == vec1.get_angle():
return Vec(self.x, self.y)
if vec1.get_angle() >= 0:
return self.set_angle(vec1.get_angle() - self.get_angle() + 90)
else:
return self.set_angle(vec1.get_angle() - self.get_angle() - 90)
(I don't know python, but I know physics and you aren't getting other answers so I'll take a crack at it.)
Look at
if self.pos.sub(p.pos).get_length() <= self.radius * ppm + p.radius * ppm:
...
rel_pos = p.pos.sub(self.pos)
shift = rel_pos.set_length(- rel_pos.get_length() + self.radius * ppm + p.radius * ppm)
p.pos = p.pos.add(shift.scale(0.50))
self.pos = self.pos.add(shift.scale(-0.50))
You're setting the length to a negative number, so you're moving the objects toward each other.
The norm_reflect() function doesn't make much sense, and I suspect it does something other than what you intend (in which case you're not testing your code).
These two lines:
self.speed = p_speed.add(self.speed.norm_reflect(rel_pos.set_angle(rel_pos.get_angle() + 90).scale(-self.friction))).scale(0.50 * self_mass_ratio)
p.speed = self_speed.add(p.speed.norm_reflect(rel_pos.set_angle(rel_pos.get_angle() + 90).scale(self.friction))).scale(0.50 * p_mass_ratio)
seem to be invoking norm_reflect() with only one argument, and you're bringing friction and mass ratios into the picture before the simple case is working, and you're reusing rel_pos after multiple transformations, and the physics is non-Newtonian (i.e. wrong enough to require starting over from a blank slate).