Next / Previous / Contents / Shipman's homepage

26. class FieldItem: Base class for encounter record fields

In order to regularize the process of scanning fixed-size fields in the raw encounter record, we define this base class so all the various encounter fields can use a standardized interface for scanning and flattening field values.

Here is the interface:

baseclasses.py
# - - - - -   c l a s s   F i e l d I t e m   - - - - -

class FieldItem:
    '''Base class for encounter record fields.

      Exports:
        FieldItem(encounter, value):      # Virtual constructor
          [ (encounter is the containing BaseEncounter) and
            (value is the field value) ->
              return a new FieldItem object with those values ]
        .encounter:    [ as passed to constructor, read-only ]
        .value:        [ as passed to constructor, read-only ]
        FieldItem.scanField(encounter, scan, fieldName):  # Static
          [ (encounter is a BaseEncounter object) and
            (scan is a Scan object) and
            (fieldName is an attribute name as a string) ->
              if  scan starts with a valid field ->
                scan  :=  scan advanced past that field
                encounter.(fieldName)  :=  an object representing
                                           that field
              else ->
                scan   :=   scan advanced no further than end of line
                Log()  +:=  error message(s)
                raise SyntaxError ]
        FieldItem.flatten(value):  # Static
          [ if value is None ->
              return a string of spaces the size of a flattened
              field representing this class
            if value is a member of this class ->
              return value flattened as a string ]
    '''

    def __init__(self, encounter, value):
        '''Default constructor for a FieldItem
        '''
        self.encounter = encounter
        self.value     = value

    @staticmethod
    def scanField(encounter, scan, fieldName):
        '''Virtual method.
        '''
        raise NotImplementedError

The idea here is that derived classes will come up with some appropriate representation of whatever can occur in the field. Then the static .scanField() method is used when we are parsing an encounter line and expect a field of this type to occur next. The .flatten() method is used by BaseEncounter.flatten() to assemble a flat-file record from the constituent fields.

One virtue of this uniform interface is that we can scan a fixed sequence of fixed-size fields using a table-driven approach. We can set up a list of tuples (className, fieldName) and work through the list, calling the .scanField() method for each class in turn, and storing the resulting object using the given field name. See Section 7, “scanFieldItems(): Parse a sequence of FieldItem objects”.