Skip to content

Commit 1d3d18b

Browse files
authored
horizontal motion code physics (#4710)
* Add files via upload * Changed print to f-string Also printed out results in a math notation * Add files via upload * Fixes: #4710 provided return type * File exists in another pull request * imported radians from math * Updated file according to pre-commit test * Updated file * Updated gamma * Deleted duplicate file * removed pi * reversed tests * Fixed angle condition * Modified prints to f-string * Update horizontal_projectile_motion.py * Update horizontal_projectile_motion.py * Fixes #4710 added exceptions and tests * Added float tests * Fixed type annotations * Fixed last annotation * Fixed annotations * fixed format * Revert "fixed format" This reverts commit 5b0249a. Undo changes @wq * Revert "Fixed annotations" This reverts commit c37bb95. * Revert "Fixed last annotation" This reverts commit e3678fd. * Revert "Fixed type annotations" This reverts commit 3f2b238. * Revert to 4e2fcaf * Fixing errors found during pre-commit
1 parent 1f1daaf commit 1d3d18b

File tree

1 file changed

+152
-0
lines changed

1 file changed

+152
-0
lines changed

Diff for: physics/horizontal_projectile_motion.py

+152
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
"""
2+
Horizontal Projectile Motion problem in physics.
3+
This algorithm solves a specific problem in which
4+
the motion starts from the ground as can be seen below:
5+
(v = 0)
6+
**
7+
* *
8+
* *
9+
* *
10+
* *
11+
* *
12+
GROUND GROUND
13+
For more info: https://en.wikipedia.org/wiki/Projectile_motion
14+
"""
15+
16+
# Importing packages
17+
from math import radians as angle_to_radians
18+
from math import sin
19+
20+
# Acceleration Constant on hearth (unit m/s^2)
21+
g = 9.80665
22+
23+
24+
def check_args(init_velocity: float, angle: float) -> None:
25+
"""
26+
Check that the arguments are valid
27+
"""
28+
29+
# Ensure valid instance
30+
if not isinstance(init_velocity, (int, float)):
31+
raise TypeError("Invalid velocity. Should be a positive number.")
32+
33+
if not isinstance(angle, (int, float)):
34+
raise TypeError("Invalid angle. Range is 1-90 degrees.")
35+
36+
# Ensure valid angle
37+
if angle > 90 or angle < 1:
38+
raise ValueError("Invalid angle. Range is 1-90 degrees.")
39+
40+
# Ensure valid velocity
41+
if init_velocity < 0:
42+
raise ValueError("Invalid velocity. Should be a positive number.")
43+
44+
45+
def horizontal_distance(init_velocity: float, angle: float) -> float:
46+
"""
47+
Returns the horizontal distance that the object cover
48+
Formula:
49+
v_0^2 * sin(2 * alpha)
50+
---------------------
51+
g
52+
v_0 - initial velocity
53+
alpha - angle
54+
>>> horizontal_distance(30, 45)
55+
91.77
56+
>>> horizontal_distance(100, 78)
57+
414.76
58+
>>> horizontal_distance(-1, 20)
59+
Traceback (most recent call last):
60+
...
61+
ValueError: Invalid velocity. Should be a positive number.
62+
>>> horizontal_distance(30, -20)
63+
Traceback (most recent call last):
64+
...
65+
ValueError: Invalid angle. Range is 1-90 degrees.
66+
"""
67+
check_args(init_velocity, angle)
68+
radians = angle_to_radians(2 * angle)
69+
return round(init_velocity**2 * sin(radians) / g, 2)
70+
71+
72+
def max_height(init_velocity: float, angle: float) -> float:
73+
"""
74+
Returns the maximum height that the object reach
75+
Formula:
76+
v_0^2 * sin^2(alpha)
77+
--------------------
78+
2g
79+
v_0 - initial velocity
80+
alpha - angle
81+
>>> max_height(30, 45)
82+
22.94
83+
>>> max_height(100, 78)
84+
487.82
85+
>>> max_height("a", 20)
86+
Traceback (most recent call last):
87+
...
88+
TypeError: Invalid velocity. Should be a positive number.
89+
>>> horizontal_distance(30, "b")
90+
Traceback (most recent call last):
91+
...
92+
TypeError: Invalid angle. Range is 1-90 degrees.
93+
"""
94+
check_args(init_velocity, angle)
95+
radians = angle_to_radians(angle)
96+
return round(init_velocity**2 * sin(radians) ** 2 / (2 * g), 2)
97+
98+
99+
def total_time(init_velocity: float, angle: float) -> float:
100+
"""
101+
Returns total time of the motion
102+
Formula:
103+
2 * v_0 * sin(alpha)
104+
--------------------
105+
g
106+
v_0 - initial velocity
107+
alpha - angle
108+
>>> total_time(30, 45)
109+
4.33
110+
>>> total_time(100, 78)
111+
19.95
112+
>>> total_time(-10, 40)
113+
Traceback (most recent call last):
114+
...
115+
ValueError: Invalid velocity. Should be a positive number.
116+
>>> total_time(30, "b")
117+
Traceback (most recent call last):
118+
...
119+
TypeError: Invalid angle. Range is 1-90 degrees.
120+
"""
121+
check_args(init_velocity, angle)
122+
radians = angle_to_radians(angle)
123+
return round(2 * init_velocity * sin(radians) / g, 2)
124+
125+
126+
def test_motion() -> None:
127+
"""
128+
>>> test_motion()
129+
"""
130+
v0, angle = 25, 20
131+
assert horizontal_distance(v0, angle) == 40.97
132+
assert max_height(v0, angle) == 3.73
133+
assert total_time(v0, angle) == 1.74
134+
135+
136+
if __name__ == "__main__":
137+
from doctest import testmod
138+
139+
testmod()
140+
141+
# Get input from user
142+
init_vel = float(input("Initial Velocity: ").strip())
143+
144+
# Get input from user
145+
angle = float(input("angle: ").strip())
146+
147+
# Print results
148+
print()
149+
print("Results: ")
150+
print(f"Horizontal Distance: {str(horizontal_distance(init_vel, angle))} [m]")
151+
print(f"Maximum Height: {str(max_height(init_vel, angle))} [m]")
152+
print(f"Total Time: {str(total_time(init_vel, angle))} [s]")

0 commit comments

Comments
 (0)