Next / Previous / Contents / TCC Help System / NM Tech homepage

14. Defect statistics

This program was written with Cleanroom intended functions. No self-verification or peer verification was done. Defects are counted from the first compilation. Defects are broken down into three categories: see Section 14.1, “Syntax errors”; Section 14.2, “Strong typing errors”; and Section 14.3, “Logic errors”.

14.1. Syntax errors

Syntax errors caught by Python while scanning modules.

  1. In function buildWeb(), the for-loop was indented one level too far, as if it were a method, not a def.

  2. In TaxonPhotoSet.__addData(), this line:

                                class_="cat-info_ )
    

    should have been:

                                class_="cat-info" )
    

  3. In FormPhotoSet.__addData(), unclosed parentheses:

                xc.Text ( noteDiv, arch.original.note
    

    should be:

                xc.Text ( noteDiv, arch.original.note )
    

14.2. Strong typing errors

These are errors that would have been caught at compile time in a more strongly typed language such as Java.

  1. Somewhere on a listing I noted that I needed a line of this form:

    import abbr as abbrModule
    

    but it never got added to the imports.

  2. Neglected to import the sys module; catweb needs it to retrieve its command line arguments.

  3. In the addArchive() function, the discussion of prime 1 states that the ArchiveIndex.readFile() method reads the index, but the code was wrong:

        archIndex  =  ArchiveIndex ( catalog, archFileName )
    

    It should be:

        archIndex  =  ArchiveIndex.readFile ( catalog, archFileName )
    

  4. In the addArchImage() function, the module containing the class constructor for BirdId was the wrong one:

            birdId  =  txny.BirdId.parse ( txny, rawBirdId )
    

    It should be:

            birdId  =  abbrModule.BirdId.parse ( txny, rawBirdId )
    

  5. In TaxonPhotoSet.__addContained(), this code:

            childTaxon  =  self.childContaining ( newTaxon )
    

    should be:

            childTaxon  =  self.taxon.childContaining ( newTaxon )
    

  6. In TaxonPhotoSet.__addContained(), this code added a Taxon object as a value in the self.__childMap dictionary, but it should have been a TaxonPhotoSet object. The erroneous code:

            try:
                childNode  =  self.__childMap [ childTaxon.txKey ]
            except KeyError:
                childNode  =  TaxonPhotoSet ( childTaxon )
                self.__childMap [ childTaxon.txKey ]  =  childTaxon
    

    Correct code:

            try:
                childNode  =  self.__childMap [ childTaxon.txKey ]
            except KeyError:
                childNode  =  TaxonPhotoSet ( childTaxon )
                self.__childMap [ childTaxon.txKey ]  =  childNode
    

  7. Neglected to import the os module; used in FormPhotoSet.pathName() to assemble directory and file names into a path.

  8. In FormPhotoSet.buildPage(), this statement has a typo:

            titleText  =  ( "Shipman's bird photo index: %s" %
                            seld.birdId.engComma() )
    

    It should be:

            titleText  =  ( "Shipman's bird photo index: %s" %
                            self.birdId.engComma() )
    

  9. In FormPhotoSet.__addThumbnail(), the call to xc.Element omitted the name of the new element:

            td  =  xc.Element ( tr, valign="top", align="center" )
    

    It should be:

            td  =  xc.Element ( tr, "td", valign="top", align="center" )
    

  10. In FormPhotoSet.__addThumbnail(), the code to extract the catalog number left out a level:

            href = "thumb/%s.jpg" % archImage.catNo
    

    It should be:

            href = "thumb/%s.jpg" % archImage.original.catNo
    

  11. In FormPhotoSet.__addSize(), I wasn't paying attention to operator precedence. Here is the erroneous code:

                xc.Text ( divPercent, "%.2f%%" %
                          100.0 * thisFramePixels / fullFramePixels )
    

    I should have parenthesized the expression on the second line. As it was, it was grouped as “("%.2f%%" % 100.0) * ...”. Better code, moving the percentage calculation to a separate line:

                framePercent  =  100.0 * thisFramePixels / fullFramePixels
                xc.Text ( divPercent, "%.2f%%" % framePercent )
    

  12. In FormPhotoSet.__addData(), this line omitted its first argument:

            if  archImage.original.loc:
                xc.Text ( ": %s" % archImage.original.loc )
    

    It should be:

            if  archImage.original.loc:
                xc.Text ( majorDiv, ": %s" % archImage.original.loc )
    

  13. In FormPhotoSet.__addData(), this line:

            # [ td  :=  td with a new div element added containing
            #           arch.original.note ]
            if  arch.original.note:
                noteDiv  =  xc.Element ( td, "div" )
                xc.Text ( noteDiv, arch.original.note )
    

    should be:

            # [ td  :=  td with a new div element added containing
            #           archImage.original.note ]
            if  archImage.original.note:
                noteDiv  =  xc.Element ( td, "div" )
                xc.Text ( noteDiv, archImage.original.note )
    

  14. In TaxonPhotoSet.__buildMultiForms(), the call to .__buildFormLine() omitted the first argument.

              self.__buildFormLine ( self.__formMap[formName] )
    

    It should be:

              self.__buildFormLine ( parent, self.__formMap[formName] )
    

14.3. Logic errors

Ordinary logic errors.

  1. Neglected to include the “pound-bang line” at the beginning, not to mention the comment pointing at this documentation.

  2. The handling of questionable identifications, such as ab6='hamfly?' for possible Hammond's Flycatcher, was completely dropped in design. I thought I had modified the BirdId class in the abbr.py module to handle this, but that modification never went in.

  3. In TaxonPhotoSet.buildPage(), neglected to implement the logic for the case where no forms refer to that taxon. The cases of one form and multiple forms were fine. If there is no form, then the taxon's name appears without being a link to anything.

  4. In FormPhotoSet.buildPage(), I wrote the line to create the new file when I was tired, and forgot basic Python:

            pageFile  =  open ( pagePath, "new" )
    

    It should be:

            pageFile  =  open ( pagePath, "w" )
    

  5. Neglected actually to write out the index page when it is finished. Added logic:

        #-- 3 --
        # [ if  index page can be created anew ->
        #     index page  :=  indexPage, serialized ]
        indexFile  =  open ( INDEX_PAGE, "w" )
        indexPage.write ( indexFile )
        indexFile.close()
    

  6. Got the URL of the stylesheet wrong:

    CSS_STYLESHEET  =  "http://www.nmt.edu/~john/scans/birds/birdindex.css"
    

    It should be:

    CSS_STYLESHEET  =  "http://www.nmt.edu/~john/scans/bird/birdindex.css"
    

  7. In TaxonPhotoSet.buildPage, the class of the div elements for higher taxa was build with the wrong separator:

            div["class"]  =  "head_%s" % self.taxon.rank.code
    

    It should be:

            div["class"]  =  "head-%s" % self.taxon.rank.code
    

  8. In FormPhotoSet.__addThumbnail(), the logic that sets up the image link is brain-dead:

            href = "thumb/%s.jpg" % archImage.original.catNo
            xc.Element ( td, "img", src="href", alt="thumbnail" )
    

    The second line should be:

            xc.Element ( td, "img", src=href, alt="thumbnail" )
    

  9. In FormPhotoSet.__addThumbnail(), the path to the thumbnail has to go up one level before it goes back down to the thumbnail directory:

            href = "thumb/%s.jpg" % archImage.original.catNo
    

    It should be:

            href = "../thumb/%s.jpg" % archImage.original.catNo
    

  10. In TaxonPhotoSet.__buildMultiForms(), neglected to place the taxon's name in the higher-taxon div. New first prime:

            #-- 1 --
            # [ parent  :=  parent with self's name added as text ]
            self.__webName ( parent )
    

  11. In FormPhotoSet.pathName(), forgot that bird codes can be right-blank padded. The cure is to call .rstrip() on all bird codes before forming them into pathnames.

  12. Neglected to implement the design goal of suppressing a genus name headings if no form is referred to it. Rewrote TaxonPhotoSet.buildPage(): don't allocate a div until we have eliminated this case.

  13. FormPhotoSet.pathName() generated the same path name for questionable forms as for regular ones. The fix is to append "-q" for questionable forms.