curriculum/challenges/english/blocks/learn-encapsulation-by-building-a-projectile-trajectory-calculator/6633b26c4f2d603072ef0818.md
It's good practice to give a representation to the class by using the __repr__ special method. While the __str__ method returns a readable string representation that's intended to be user friendly, __repr__ is intended for programmers. Often __repr__ provides a string that can be used to recreate the object.
Write the __repr__ method, which will return the string needed to instantiate the object.
You can test this by calling the repr function and passing it an instance of the class.
The Projectile class should have a __repr__ method.
({
test: () => assert(runPython(
`_Node(_code).find_class('Projectile').has_function('__repr__')`
))
})
The instance Projectile(12, 12, 12) should have representation equal to 'Projectile(12, 12, 12)'.
({
test: () => assert(runPython(
`repr(Projectile(12, 12, 12)) == 'Projectile(12, 12, 12)' or \\
repr(Projectile(12, 12, 12)) == 'Projectile(12, 12, 12.0)'`
))
})
The instance Projectile(21, 22, 45) should have representation equal to 'Projectile(21, 22, 45)'.
({
test: () => assert(runPython(
`repr(Projectile(21, 22, 45)) == 'Projectile(21, 22, 45)' or \\
repr(Projectile(21, 22, 45)) == 'Projectile(21, 22, 45.0)'`
))
})
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)
def __str__(self):
return f'''
Projectile details:
speed: {self.speed} m/s
height: {self.height} m
angle: {self.angle}°
displacement: {round(self.__calculate_displacement(), 1)} m
'''
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
--fcc-editable-region--
--fcc-editable-region--
ball = Projectile(10, 3, 45)
print(ball)
coordinates = ball.calculate_all_coordinates()