curriculum/challenges/english/blocks/learn-encapsulation-by-building-a-projectile-trajectory-calculator/66671a41b55e531d08ab82b5.md
The __str__ method refers to the attributes of the class directly, but now that you have created the getters it is better to use those to obtain those values.
Edit the __str__ method to not reference the attributes anymore, but to use the getters.
The string representation for Projectile(45, 45, 45) should be correct.
({test: () => assert(runPython(
`
ball = Projectile(45, 45, 45)
str(ball) == """
Projectile details:
speed: 45 m/s
height: 45 m
angle: 45°
displacement: 244.4 m
"""`
))})
The string representation should also be correct for other instances.
({test: () => assert(runPython(`p = Projectile(10, 10, 10)
str(
p
) == """
Projectile details:
speed: 10 m/s
height: 10 m
angle: 10°
displacement: 15.9 m
"""`))})
You should not be referencing the private properties directly.
({
test: () => runPython(`
rtrn = str(_Node(_code).find_class('Projectile').find_function('__str__').find_return())
assert not 'self.__angle' in rtrn
assert not 'self.__speed' in rtrn
assert not 'self.__height' in rtrn
`)
})
import math
GRAVITATIONAL_ACCELERATION = 9.81
PROJECTILE = "∙"
x_axis_tick = "T"
y_axis_tick = "⊣"
class Projectile:
__slots__ = ('__speed', '__height', '__angle')
def __init__(self, speed, height, angle):
self.__speed = speed
self.__height = height
self.__angle = math.radians(angle)
--fcc-editable-region--
def __str__(self):
return f'''
Projectile details:
speed: {self.__speed} m/s
height: {self.__height} m
angle: {round(math.degrees(self.__angle))}°
displacement: {round(self.__calculate_displacement(), 1)} m
'''
--fcc-editable-region--
def __calculate_displacement(self):
horizontal_component = self.__speed * math.cos(self.__angle)
vertical_component = self.__speed * math.sin(self.__angle)
squared_component = vertical_component**2
gh_component = 2 * GRAVITATIONAL_ACCELERATION * self.__height
sqrt_component = math.sqrt(squared_component + gh_component)
return horizontal_component * (vertical_component + sqrt_component) / GRAVITATIONAL_ACCELERATION
def __calculate_y_coordinate(self, x):
height_component = self.__height
angle_component = math.tan(self.__angle) * x
acceleration_component = GRAVITATIONAL_ACCELERATION * x ** 2 / (
2 * self.__speed ** 2 * math.cos(self.__angle) ** 2)
y_coordinate = height_component + angle_component - acceleration_component
return y_coordinate
def calculate_all_coordinates(self):
return [
(x, self.__calculate_y_coordinate(x))
for x in range(math.ceil(self.__calculate_displacement()))
]
@property
def height(self):
return self.__height
@property
def angle(self):
return round(math.degrees(self.__angle))
@property
def speed(self):
return self.__speed
@height.setter
def height(self, n):
self.__height = n
@angle.setter
def angle(self, n):
self.__angle = math.radians(n)
@speed.setter
def speed(self, s):
self.__speed = s
ball = Projectile(10, 3, 45)
print(ball)
coordinates = ball.calculate_all_coordinates()