9
\$\begingroup\$

I'm learning the kinematic equations in Concepts of Engineering and so here are the equations I am learning:

enter image description here

To complete the lesson, I was told to create a Python program that outputs the horizontal velocity and the maximum height of the projectile. Here is my program:

# x = v_x * t + x_0
# y = 0.5(g * (t**2)) + v_y0 * t + y_0
# v_y = v_y0 + g* t
# v_y ** 2 = 2*g*y + v_y0 ** 2

# Input is time, x-range, launch angle, starting coordindates of launch (defined as 0,0)
time = float(raw_input("What was the time in seconds: "))
x_range = float(raw_input("How far was the projectile launched horizontally in feet: "))
launch_angle = float(raw_input("What was the launch angle in degrees: "))

x_o, y_o = 0, 0 
gravity = -32.2 
v_y = 0

# Horizontal velocity in mph
v_x = ((x_range - x_o)/time * 3600)/5280
print "\nThe horizontal velocity is {0:} miles per hour".format(v_x)

# Maximum height in feet
vy = 0
v_yo = vy - gravity * (time/2)
height = 0.5 * (gravity * ((time/2) ** 2)) + (v_yo * (time/2)) + 0
print "The maximum height is {0:} feet".format(height)

My current questions are:

  • How can my code become smaller and/or more Pythonic?

  • Could my code and/or equations be simplified in any way?

  • How can the readability of my program be improved?

For now, the launch angle does not affect the results and just there because of the specs. Example output:

What was the time in seconds:  1.2
How far was the projectile launched horizontally in feet:  3
What was the launch angle in degrees:  45

The horizontal velocity is 1.70454545455 miles per hour
The maximum height is 5.796 feet
\$\endgroup\$

2 Answers 2

6
\$\begingroup\$

I would improve the following things:

  • define all the constants - e.g. 3600 and 5280 might be clear for you or for you now, but may not be for you in the future of for the other person. Or, in this case, it might be better to have a generic convert_to_mph() function
  • use an upper case for the constant values (PEP8 recommendation)
  • you are defining v_y and vy two times - I think you meant to do it once
  • y_o variable is not used
  • add extra spaces around the arithmetic operators (PEP8 recommendation)
  • use print() function and not statement (for Python 2 and 3 compatibility)
  • typo: "coordindates" -> "coordinates"

Improved version:

X_O = 0
GRAVITY = -32.2
V_Y = 0


def convert_to_mph(value):
    """Converts velocity from m/s to mph. TODO: what formula used?"""
    return value * 3600 / 5280


# Input is time, x-range, launch angle, starting coordinates of launch (defined as 0,0)
time = float(raw_input("What was the time in seconds: "))
x_range = float(raw_input("How far was the projectile launched horizontally in feet: "))
launch_angle = float(raw_input("What was the launch angle in degrees: "))

# Horizontal velocity
v_x = (x_range - X_O) / time
v_x_mph = convert_to_mph(v_x)
print("\nThe horizontal velocity is {0:} miles per hour".format(v_x_mph))

# Maximum height
v_yo = V_Y - GRAVITY * (time / 2)
height = 0.5 * (GRAVITY * ((time / 2) ** 2)) + (v_yo * (time / 2)) + 0
print("The maximum height is {0:} feet".format(height))

You can further improve the code by introducing separate functions for calculating horizontal velocity and the maximum height. If you do this the comments before the code blocks would naturally transform into function docstrings (which you would need to improve adding more information about how the resulting values are calculated) making the code more pythonic.

Also, the meter to feet conversion should also be done via a separate generic function like convert_to_mph for the velocity.

And, as a side note, from the usability perspective, there is no validation of the user input values.


You can also use a Python 2 and 3 compatible way to obtain a user input:

try:
   input = raw_input
except NameError:
   pass

time = float(input("What was the time in seconds: "))
x_range = float(input("How far was the projectile launched horizontally in feet: "))
launch_angle = float(input("What was the launch angle in degrees: "))

But that would depend on how important the compatibility is for you at this point.

\$\endgroup\$
6
\$\begingroup\$

You have a lot of redundancy here!

First of all, you are asking too many questions. If you have a cannon whose launch angle is fixed, the only variable you could possibly control about the launch is the initial launch speed. There aren't three independent variables.

Specifically, the horizontal velocity is only based on range and flight duration:

$$v_x = \frac{r}{t}$$

The height is only dependent on the gravitational acceleration and duration:

$$h = \frac{1}{2} g \left(\frac{t}{2}\right)^2 = \frac{gt^2}{8}$$

So, define two functions:

def v_x(distance, duration):
    """Horizontal velocity of projectile, given the distance and duration"""
    return …

def h(duration):
    """Maximum height of projectile, given the flight duration"""
    return …

Always label all numbers with the appropriate units. For example:

GRAVITY = -32.2     # Feet per second per second

Better yet, use a library (such as SymPy, numericalunits, or pint) to help manage your units.

\$\endgroup\$
1
  • \$\begingroup\$ Sorry about the variables... the way my teacher did it required all three (though the effect of the launch angle isn't present) \$\endgroup\$ Commented Jan 17, 2017 at 22:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.