Program Structure
Python is very flexible in terms of program structure. That is, the syntax does not require a specific ordering to functions or classes within a module or methods within a class. (Note, however, that functions and classes must be defined before they can be used.) But large programs can quickly become unmanageable and difficult to read. This section outlines several requirements in terms of program structure. The Main DriverThe Python source file that contains the starting point or the first instruction to be executed is known as the driver module. There are two styles that can be used for organizing the driver module, depending on whether functions are used. In no case should a class be defined within the driver module. Driver Without FunctionsThe first statement to be executed is the first statement at file level (outside all functions and class definitions). For simple drivers that do not need to be organized into multiple functions, all statements can be at file level as illustrated by the sample program below. For this style, which does not include any function definitions, you are to use the following structure:
#---------------------------------------------------------- # sample.py # # Created by: John Q. Smith # # A simple program that prompts for a real value and computes # its square root. #---------------------------------------------------------- x = float( input("Enter a real value:") ) y = math.sqrt( x ) print( "The square root of", x, "is", y ) Driver With FunctionsLarge driver modules should be organized into multiple functions and include a
#---------------------------------------------------------- # diceroll.py # # Created by: R. Necaise # # Simulates the rolling of two dice. #---------------------------------------------------------- from random import * # Minimum number of sides on a die. MIN_SIDES = 4 # Our very own main routine for a top-down design. def main(): print( "Dice roll simulation." ) numSides = int( input("How many sides should the die have? ") ) if numSides < MIN_SIDES : numSides = MIN_SIDES value = rollDice( numSides ) print( "You rolled a", value ) # Simulate the rollowing of two nSided dice. def rollDice( nSides ): die1 = randint( 1, nSides + 1 ) die2 = randint( 1, nSides + 1 ) return die1 + die2 # Call the main routine which we defined first. main() ModulesModules can contain any combination of function and class definitions, constant and non-constant variable declarations and executable statements. In this course, all non-driver modules will be limited to class definitions and constant variable declarations and should be organized as follows:
One Public Class. If a module contains a single public class:
For example, the following code segment illustrates the definition of two classes, one public and the other private. #---------------------------------------------------------- # linearbag.py # # Implementation of the Bag ADT using a Python list. #---------------------------------------------------------- class Bag : # Constructs an empty bag. def __init__( self ): self._theItems = list() ..... def __iter__( self ): return _BagIterator( self._theItems ) # Defines the iterator used with a Bag. class _BagIterator : ...... Multiple Public Classes. If a module contains multiple public class definitions:
The following code segment illustrates a module containing several public classes, all of which are related to array definitions. #---------------------------------------------------------- # array.py # # Implementation of the various array structures. #---------------------------------------------------------- # Defines a 1-D array implemented using hardware supported arrays. class Array : ...... # Defines a 2-D array implemented as an array of arrays. class Array2D : ...... # Defines a multi-dimensional array using a single 1-D array and # row-major ordering. class MultiArray : ...... ClassesTo aide in readability and understanding of a class definition, the class should be well structured and documented. The comments required for a class and its methods are described in the "Comments" section. Organization. The methods defined for a class can technically occur in any order. To provide a well structured implementation and to aide the reader, you are to use the following structure:
Leave at least one and no more than two blank lines between the method definitions. The following example illustrates a fully commented and well structured class definition. # ----------------------------------------------------------------------- # Defines a point in the 2-D Cartesian coordinate system. The points can # be either integers or floating-point values. # ----------------------------------------------------------------------- class Point : # Creates a point object from the supplied coordinates. def __init__( self, x, y ): self._xCoord = x self._yCoord = y # Returns the x coordinate of the point. def getX( self ): return self._xCoord # Returns the y coordinate of the point. def getY( self ): return self._yCoord # Computes and returns the distance between this point and the otherPoint. def distance( self, otherPoint ): xDiff = self._xCoord - otherPoint._xCoord yDiff = self._yCoord - otherPoint._yCoord return math.sqrt( xDiff ** 2 + yDiff ** 2 ) # Determines if this point is the same as the otherPoint. def __eq__( self, otherPoint ): return self._xCoord == otherPoint._xCoord and self._yCoord == otherPoint._yCoord Storage ClassesA storage class is used to create objects for simply storing structured or multi-component data items. Typically, they only contain a constructor used to create and initialize the various data fields. Any class or code segment that has access to the storage class can directly reference the various data attributes. # ----------------------------------------------------------------------- # Defines a private storage class for use with the Map ADT implemented # using a Python list. # ----------------------------------------------------------------------- class MapElement : def __init__( self, key, value ): self.key = key self.value = value
|