Exercises for Lesson 18
Exercise 1: Modularizing cannonball
Here is the full cannonball program:
# cannonball_main.py
import math
def main():
# Get inputs
angle = float(input("Enter the launch angle (in degrees): "))
vel = float(input("Enter the initial velocity (in meters/sec): "))
h0 = float(input("Enter the initial height (in meters): "))
dt = float(input("Enter the time step: "))
# Convert angle to readians
theta = math.radians(angle)
# Set the initial position and velocity in x and y directions
xpos = 0
ypos = h0
xvel = vel * math.cos(theta)
yvel = vel * math.sin(theta)
# Loop until the ball hits the ground
while ypos >= 0.0:
# Update the x position; x velocity doesn't change
xpos += dt * xvel
# Update the y position and velocity (due to gravity)
yvelNew = yvel - dt * 9.8
ypos += dt * (yvel + yvelNew)/2.0 # use average velocity
yvel = yvelNew
print("Distance traveled: {0:0.1f} meters.".format(xpos))
if __name__ == "__main__":
main()
Let’s modularize this program by breaking it into different functions. (This is kind of the opposite of top-down design. We’re “refactoring” the code after it’s been written.) Here is what main
will look like when we’re done:
# cannonball_main.py
import math
def main():
angle, vel, h0, dt = getInputs()
xpos, ypos = 0, h0
xvel, yvel = getXYComponents(vel, angle)
while ypos >= 0.0:
xpos, ypos, yvel = updateCannonball(dt, xpos, ypos, xvel, yvel)
print("Distance traveled: {0:0.1f} meters.".format(xpos))
if __name__ == "__main__":
main()
Part a: getting input
First, write a function to get the user inputs.
Old:
# Get inputs
angle = float(input("Enter the launch angle (in degrees): "))
vel = float(input("Enter the initial velocity (in meters/sec): "))
h0 = float(input("Enter the initial height (in meters): "))
dt = float(input("Enter the time step: "))
New:
angle, vel, h0, dt = getInputs()
Part b: calculating the directional velocity components
Next, write a function to compute the x and y components of velocity.
Old:
# Convert angle to readians
theta = math.radians(angle)
# Set the initial position and velocity in x and y directions
xpos = 0
ypos = h0
xvel = vel * math.cos(theta)
yvel = vel * math.sin(theta)
New:
xpos, ypos = 0, h0
xvel, yvel = getXYComponents(vel, angle)
Part c: updating the cannonball
Finally, write a function to calculate the new cannonball state.
Old:
# Update the x position; x velocity doesn't change
xpos += dt * xvel
# Update the y position and velocity (due to gravity)
yvelNew = yvel - dt * 9.8
ypos += dt * (yvel + yvelNew)/2.0 # use average velocity
yvel = yvelNew
New:
xpos, ypos, yvel = updateCannonball(dt, xpos, ypos, xvel, yvel)
Exercise 2: The Projectile
constructor
We want to rewrite our code again to use a Projectile
class. Here is what main
will look like now:
def main():
angle, vel, h0, dt = getInputs()
cannonball = Projectile(angle, vel, h0)
while cannonball.getY() >= 0.0:
cannonball.update(dt)
print("Distance traveled: {0:0.1f} meters.".format(cannonball.getX()))
Fill in the constructor for the Projectile
class. We want to characterize a projectile given the four values of its x and y coordinates of position and velocity. In addition, add accessor methods for the x and y positions.
class Projectile:
pass # TODO
Exercise 3: Updating a Projectile
’s state
The last piece we need is the ability to update the state of a projectile after some amount of time has passed. Complete the update
method for the Projectile
class.
def update(self, dt):
pass # TODO
Looking for the full code? Check out Zelle pages 326-237.