#### Horizontal Projectile Motion

p
```"""
Horizontal Projectile Motion problem in physics.
This algorithm solves a specific problem in which
the motion starts from the ground as can be seen below:
(v = 0)
*  *
*          *
*                *
*                    *
*                        *
*                          *
GROUND                      GROUND
"""

# Importing packages
from math import sin

# Acceleration Constant on Earth (unit m/s^2)
g = 9.80665

def check_args(init_velocity: float, angle: float) -> None:
"""
Check that the arguments are valid
"""

# Ensure valid instance
if not isinstance(init_velocity, (int, float)):
raise TypeError("Invalid velocity. Should be a positive number.")

if not isinstance(angle, (int, float)):
raise TypeError("Invalid angle. Range is 1-90 degrees.")

# Ensure valid angle
if angle > 90 or angle < 1:
raise ValueError("Invalid angle. Range is 1-90 degrees.")

# Ensure valid velocity
if init_velocity < 0:
raise ValueError("Invalid velocity. Should be a positive number.")

def horizontal_distance(init_velocity: float, angle: float) -> float:
"""
Returns the horizontal distance that the object cover
Formula:
v_0^2 * sin(2 * alpha)
---------------------
g
v_0 - initial velocity
alpha - angle
>>> horizontal_distance(30, 45)
91.77
>>> horizontal_distance(100, 78)
414.76
>>> horizontal_distance(-1, 20)
Traceback (most recent call last):
...
ValueError: Invalid velocity. Should be a positive number.
>>> horizontal_distance(30, -20)
Traceback (most recent call last):
...
ValueError: Invalid angle. Range is 1-90 degrees.
"""
check_args(init_velocity, angle)
return round(init_velocity**2 * sin(radians) / g, 2)

def max_height(init_velocity: float, angle: float) -> float:
"""
Returns the maximum height that the object reach
Formula:
v_0^2 * sin^2(alpha)
--------------------
2g
v_0 - initial velocity
alpha - angle
>>> max_height(30, 45)
22.94
>>> max_height(100, 78)
487.82
>>> max_height("a", 20)
Traceback (most recent call last):
...
TypeError: Invalid velocity. Should be a positive number.
>>> horizontal_distance(30, "b")
Traceback (most recent call last):
...
TypeError: Invalid angle. Range is 1-90 degrees.
"""
check_args(init_velocity, angle)
return round(init_velocity**2 * sin(radians) ** 2 / (2 * g), 2)

def total_time(init_velocity: float, angle: float) -> float:
"""
Returns total time of the motion
Formula:
2 * v_0 * sin(alpha)
--------------------
g
v_0 - initial velocity
alpha - angle
>>> total_time(30, 45)
4.33
>>> total_time(100, 78)
19.95
>>> total_time(-10, 40)
Traceback (most recent call last):
...
ValueError: Invalid velocity. Should be a positive number.
>>> total_time(30, "b")
Traceback (most recent call last):
...
TypeError: Invalid angle. Range is 1-90 degrees.
"""
check_args(init_velocity, angle)
return round(2 * init_velocity * sin(radians) / g, 2)

def test_motion() -> None:
"""
>>> test_motion()
"""
v0, angle = 25, 20
assert horizontal_distance(v0, angle) == 40.97
assert max_height(v0, angle) == 3.73
assert total_time(v0, angle) == 1.74

if __name__ == "__main__":
from doctest import testmod

testmod()

# Get input from user
init_vel = float(input("Initial Velocity: ").strip())

# Get input from user
angle = float(input("angle: ").strip())

# Print results
print()
print("Results: ")
print(f"Horizontal Distance: {horizontal_distance(init_vel, angle)!s} [m]")
print(f"Maximum Height: {max_height(init_vel, angle)!s} [m]")
print(f"Total Time: {total_time(init_vel, angle)!s} [s]")
```