Putting Classes in Modules

Often a well-defined class or set of classes provide(s) useful abstractions that can be leveraged in many different programs. We might want to turn our projectile class into its own module file so that it can be used in other programs. In doing so, it would be a good idea to add documentation that describes how the class can be used so that programmers who want to use the module don't have to study the code to figure out (or remember) what the class and its methods do.

You are already familiar with one way of documenting programs, namely comments. It's always a good idea to provide comments explaining the contents of a module and its uses. In fact, comments of this sort are so important that Python incorporates a special kind of commenting convention called a docstring. You can insert a plain string literal as the first line of a module, class or function to document that component. The advantage of docstrings is that, while ordinary comments are simply ignored by Python, docstrings are actually carried along during execution in a special attribute called __doc___These strings can be examined dynamically.

Most of the Python library modules have extensive docstrings that you can use to get help on using the module or its contents. For example, if you can't remember how to use the randrange function, you can print its docstring like this:

>>> print random.randrange._doc_

Choose a random item from range(start, stop[, step]).

Here is a version of our Projectile class as a module file with docstrings included: # projectile.py """projectile.py

Provides a simple class for modeling the flight of projectiles.""" from math import pi, sin, cos class Projectile:

"""Simulates the flight of simple projectiles near the earth's surface, ignoring wind resistance. Tracking is done in two dimensions, height (y) and distance (x)."""

def _init_(self, angle, velocity, height):

"""Create a projectile with given launch angle, initial velocity and height."""

self.xvel = velocity * cos(theta)

self.yvel = velocity * sin(theta)

def update(self, time):

"""Update the state of this projectile to move it time seconds farther into its flight"""

self.xpos = self.xpos + time * self.xvel yvell = self.yvel - 9.8 * time self.ypos = self.ypos + time * (self.yvel + yvell) / 2.0 self.yvel = yvell def getY(self):

"Returns the y position (height) of this projectile." return self.ypos def getX(self):

"Returns the x position (distance) of this projectile." return self.xpos

You might notice that many of the docstrings in this code are enclosed in triple quotes ("""). This is a third way that Python allows string literals to be delimited. Triple quoting allows us to directly type multi-line strings. Here is an example of how the docstrings appear when they are printed.

>>> print projectile.Projectile._doc_

Simulates the flight of simple projectiles near the earth's surface, ignoring wind resistance. Tracking is done in two dimensions, height (y) and distance (x).

Our main program could now simply import this module in order to solve the original problem. # cball4.py from projectile import Projectile def getInputs():

a = input("Enter the launch angle (in degrees): ") v = input("Enter the initial velocity (in meters/sec): ") h = input("Enter the initial height (in meters): ")

t = input("Enter the time interval between position calculations: ") return a,v,h,t def main():

angle, vel, h0, time = getInputs() cball = Projectile(angle, vel, h0) while cball.getY() >= 0:

cball.update(time) print "\nDistance traveled: %0.1f meters." % (cball.getX())

In this version, details of projectile motion are now hidden in the projectile module file.

Was this article helpful?

0 0

Post a comment