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

25. Defects discovered

This is a list of the defects discovered since first execution of the script. They are divided into three categories:

25.1. Syntax errors

  1. In buildIndex(), neglected to close parentheses:

            print >>sys.stderr, ( '*** Can't write the index page '
                "'%s'." % indexName
    

    should be:

            print >>sys.stderr, ( "*** Can't write the index page "
                "'%s'." % indexName )
    

  2. In indexBoilerplate, an unclosed string constant:

        conLink.tail  =  ( " for notational conventions and the "
                           "author's contact information. )
    

    should be:

        conLink.tail  =  ( " for notational conventions and the "
                           "author's contact information." )
    

  3. In YearRow.readOneMonth(), unclosed parenthesis.

                print >>sys.stderr, ( "*** Invalid monthly file "
                    "'%s': %s" % (monthFileName, detail) )
    

    should be:

                print >>sys.stderr, ( "*** Invalid monthly file "
                    "'%s': %s" % (monthFileName, detail) )
    

  4. In MonthCell.__notablesBlock(), unclosed string constant.

            self.__span ( div, NOTABLE_CLASS, 'Notable: )
    

    should be:

            self.__span ( div, NOTABLE_CLASS, 'Notable:' )
    

25.2. Logic errors

  1. In YearRow.readOneMonth(), neglected to prepend the year number and a slash to the actual file name passed to birdNoteSet.readFile().

  2. There's no need to add an h1 heading in the page body, because tccpage2 supplies one already. Remove this logic from indexBoilerPlate().

  3. In YearRow.readOneMonth(), the intended function was correct, but the code was wrong:

            # [ self.__monthMap[mm]  :=  a new MonthCell instance
            #       with self as the parent, month=mm, and
            #       birdNoteSet=birdNoteSet ]
            monthCell  =  MonthCell ( self, mm, birdNoteSet )
    

    should be:

            self.__monthMap[mm]  =  MonthCell ( self, mm, birdNoteSet )
    

  4. In buildRow(), neglected to place the year into the cell.

        # [ tr  +:=  a th element with class=ROW_LABEL_CLASS
        #            containing yearRow.yyyy ]
        rowLabel  =  et.SubElement ( tr, 'th' )
        rowLabel.attrib['class']  =  ROW_LABEL_CLASS    
    

    Add this line:

        rowLabel.text  =  yearRow.yyyy
    

  5. In YearCollection.findNext(), this logic returned a month number 'mm' when it should have returned a full key 'yyyy-mm'.

            # [ if any year with a key in yyyyList[pos+1:] has at
            #   least one month in it ->
            #     return the yyyy-mm key of the first month in
            #     the first such year
            #   else -> I ]
            for nextYear in yyyyList[pos+1:]:
                nextRow =  self[nextYear]
                if len(nextRow) > 0:
                    return nextRow.firstMonth()
    

    Make that last line:

                    firstMM  =  nextRow.firstMonth()
                    return '%s-%s' % (nextYear, firstMM)
    

    Symmetrical fix in YearCollection.findPrev():

                if len(prevRow) > 0:
                    lastMM  =  prevRow.lastMonth()
                    return '%s-%s' % (prevYear, lastMM)
    

  6. MonthCell.__pageFrame() completely neglected to consider the case where either the previous or next page link is None. Pretty much rewrote the whole method.

  7. In MonthCell.__sightNotes(), a cut-and-paste error:

            if sightNotes.voc is not None:
                self.__annoBlock ( parent, 'Vocalizations:',
                                   sightNotes.behavior )
    

    The last statement should be:

                self.__annoBlock ( parent, 'Vocalizations:',
                                   sightNotes.voc )
    

    Several quite similar errors in MonthCell.__dayAnnotation:

            #-- 2 --
            if daySummary.weather is not None:
                self.__annoBlock ( parent, 'Weather', daySummary.route )
    
            #-- 3 --
            if daySummary.missed is not None:
                self.__annoBlock ( parent, 'Missed', daySummary.route )
    

  8. Completely forgot about photo links.

25.3. Run-time type matching errors

  1. In YearCollection.addYear(), the call to the YearRow constructor is missing the second (txny) argument, because it was written before the constructor was fleshed out.

            yearRow  =  YearRow ( self, yyyy )
    

    should be:

            yearRow  =  YearRow ( self, txny, yyyy )
    

    which means of course that the YearCollection.addYear() method also needs this argument, and the call to that method in findYears() must also supply it.

  2. In YearRow.readOneMonth(), the reference to the BirdNoteSet constructor was not properly qualified with its containing module name.

     # [
                birdNoteSet := a new BirdNoteSet instance with #
                taxonomy self.txny ] birdNoteSet = BirdNoteSet ( txny
                )
    

    should be:

            # [ birdNoteSet  :=  a new birdnotes.BirdNoteSet instance
            #       with taxonomy self.txny ]
            birdNoteSet  =  birdnotes.BirdNoteSet ( txny )
    

  3. In the same line as the previous defect, txny should be self.txny.

            # [ birdNoteSet  :=  a new birdnotes.BirdNoteSet instance
            #       with taxonomy self.txny ]
            birdNoteSet  =  birdnotes.BirdNoteSet ( self.txny )
    

  4. The declaration of MONTH_SEASON_MAP was cut and pasted from MONTH_NAME_MAP, and I changed the content but forgot to change the name.

  5. Spelling error in YearRow.successor():

        def succesor ( self, mm ):
    

    Try:

        def successor ( self, mm ):
    

  6. In YearCollection.__findNext(), this line:

            pos  =  yyyyList.index ( yyyyy )
    

    should be:

            pos  =  yyyyList.index ( yyyy )
    

  7. Method MonthCell.__pageFrame() was declared with two arguments prevURL and nextURL, but the caller was supplying only the “yyyy-mm” key of those months, and the URLs of the target pages were developed inside the method. Change the method's starting lines from:

        def __pageFrame ( self, prevURL, nextURL ):
            '''Set up an empty tccpage2.TCCPage instance.
    
              [ (prevURL is the URL of the previous month page or None) and
              [ (nextURL is the URL of the next month page or None) ->
                  return a new TCCPage instance with navigation links
                  prevURL and nextURL ]
            '''
    

    to:

        def __pageFrame ( self, prev, next ):
            '''Set up an empty tccpage2.TCCPage instance.
    
              [ (prev is the 'yyyy-mm' of the previous month or None) and
              [ (next is the 'yyyy-mm' of the next month or None) ->
                  return a new TCCPage instance with navigation links
                  previous=(prev's page) and next=(next's page) ]
            '''
    

  8. Symmetric errors in both YearRow.firstMonth() and YearRow.lastMonth(): they were supposed to return the month key 'mm', not the entire MonthCell. Here is the fix for YearRow.firstMonth():

            return self[monthKeyList[0]]
    

    should be:

            return self[monthKeyList[0]].mm
    

  9. MonthCell.__renderPage() was declared as MonthCell.renderPage(). This happened during a general renaming of methods of this class so that all the internal methods started with “__”.

  10. Left out the self argument in MonthCell.__renderPage() and also in MonthCell.__pageTOC().

  11. In MonthCell.__pageTOC, the intended function was correct, but two lines were missing from the code:

            #-- 1 --
            # [ parent  :=  parent with a new 'ul' child element added
            #   ul  :=  that child
            #   anchorSet  :=  a new, empty set
            #   anchorMap  :=  a new, empty dictionary ]
            ul  =  et.SubElement ( parent, 'ul' )
    

    Here are the missing lines:

            anchorSet  =  set()
            anchorMap  =  {}
    

  12. In MonthCell.__dayTOC(), these lines:

            newAnchor  =  self.birdNoteSet.date
            suffix  =  'a'
            while newAnchor in anchorSet:
                newAnchor  =  self.birdNoteSet.date+suffix
                suffix  =  chr(ord(suffix)+1)
    

    were trying to extract the date from the wrong place. It should be:

            newAnchor  =  dayNotes.date
            suffix  =  'a'
            while newAnchor in anchorSet:
                newAnchor  =  dayNotes.date+suffix
                suffix  =  chr(ord(suffix)+1)
    

  13. In MonthCell.__dayTOC(), this line:

            a  =  et.SubElement ( 'a', href=('#'+newAnchor) )
    

    omitted the first argument, and should be:

            a  =  et.SubElement ( li, 'a', href=('#'+newAnchor) )
    

  14. In MonthCell.__notablesBlock(), this line:

            div  =  et.SubElement ( parent )
    

    should be:

            div  =  et.SubElement ( parent, 'div' )
    

  15. The declaration of DAY_SUMMARY_CLASS omitted the actual declaration.

  16. The declaration of MonthCell.__locDef() was erroneously coded as .__locDefs().

  17. In MonthCell.__paragraph(), this line:

                    div.addTextMixed ( div, s )
    

    should be:

                    tccpage2.addTextMixed ( div, s )
    

  18. In MonthCell.__singleSighting(), there were four references to div that should have been to parent.

  19. In MonthCell-ageSexGroup(), I blithely assumed that GENUS_CLASS had already been defined during the coding of MonthCell.__paragraph(), but it hadn't: in the latter routine, the class name comes from the input. Solution: define it.

  20. In buildMonthCell(), omitted the parent argument from SubElement():

        a  =  et.SubElement ( 'a', href=monthFileName )
    

    should be:

        a  =  et.SubElement ( td, 'a', href=monthFileName )
    

  21. In YearRow.predecessor(), after finding the position of the given month in the list mmList, the value mm was compared, not its position. So in this code:

            #-- 3 --
            if mm >= len(mmList):
                raise KeyError
            else:
                return mmList[pos+1]
    

    the first line should be:

            if pos+1 > len(mmList):
    

    Also, thanks to the wonders of cut'n'paste, YearRow.successor() had the same error.