curriculum/challenges/english/blocks/learn-encapsulation-by-building-a-projectile-trajectory-calculator/66335223f3e2a31d62d84367.md
Going back to the projectile trajectory calculator, now you'll create a new class that accepts a list of coordinates and creates the trajectory drawing.
Create a new class Graph, which should be instantiated with a private attribute __coordinates where the list of coordinates is stored. Declare the __slots__ class variable and define the __init__ and __repr__ special methods.
Also, create a Graph instance passing the coordinates variable and assign it to a new graph variable.
You should create a new Graph class.
({
test: () => assert(runPython(
`_Node(_code).has_class('Graph')`
))
})
You should have the __slots__ variable inside the class.
({
test: () => assert(runPython(
`_Node(_code).find_class('Graph').has_variable('__slots__')`
))
})
The __slots__ variable should have a value of ('__coordinates') or ['__coordinates'].
({
test: () => (runPython(
`
slots = _Node(_code).find_class('Graph').find_variable('__slots__')
assert any(slots.is_equivalent(str) for str in ['__slots__ = ("__coordinates")', '__slots__ = ["__coordinates"]'])`
))
})
You should have an __init__ method.
({
test: () => assert(runPython(
`_Node(_code).find_class('Graph').has_function('__init__')`
))
})
The __init__ method should instantiate the __coordinates private property with the passed in value.
({
test: () => assert(runPython(
`
l = [(3, 4), (4, 1), (3, 9)]
g = Graph(l)
g._Graph__coordinates == l
`
))
})
You should have a __repr__ method.
({
test: () => assert(runPython(
`_Node(_code).find_class('Graph').has_function('__repr__')`
))
})
The __repr__ method should return the correct string.
({
test: () => assert(runPython(
`
ball = Projectile(10, 3, 45)
coords = ball.calculate_all_coordinates()
repr(Graph(coords)) == f'Graph({coords})'
`
))
})
You should create a Graph instance passing in the coordinates variable and assign it to graph variable.
({
test: () => {
runPython(`
assert _Node(_code).has_variable('graph'), "variable graph is missing"
assert _Node(_code).find_variable('graph').is_equivalent('graph = Graph(coordinates)'), "assignment to graph is wrong"
`)
}
})
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
def __repr__(self):
return f"{self.__class__.__name__}({self.speed}, {self.height}, {self.angle})"
--fcc-editable-region--
ball = Projectile(10, 3, 45)
print(ball)
coordinates = ball.calculate_all_coordinates()
--fcc-editable-region--