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

24. yearBrackets(): Display a bracketed list of years worked

When displaying the list of years when a particular circle was counted, the general case is actually fairly complex, because years can be skipped, and (especially in the early decades) many circles were counted more than once in a year. Here are some examples.

[38] Counted once in year 38.
[72–84] Counted every year from the 72nd through the 84th.
[72–79,81–84] Counted from the 72nd through the 84th but missed the 80th.
[1,7(5),8(4),9(3),11,35, 37–72] Typical circle (Belmont, MA) in the early years: lots of multiply-counted years.
[4-6,7(2)] The raw list of years for this case is [4, 5, 6, 7, 7]. Note that the range starting with 4 ends at 6, not 7, because the 7 is repeated.

Our effortList argument is a list of Effort instances as input. Our task is to form these into hyphenated groups, but avoid combining ranges with multiply-counted years. Here is the algorithm.

  1. We set numberList to a list of the year numbers in the effortList. We also set up a resultList which will hold the character form of each resulting group.

  2. From this, we first form pairList, a list of pairs (year_no, count), sorted by year number.

  3. We find which set of one or more initial rows of pairList form a group. We then remove those rows and add the equivalent character representation to resultList. This step is repeated until pairList is exhausted.

  4. The result is the concatenated elements of resultList, separated by commas and enclosed in brackets.
# - - -   y e a r B r a c k e t s

def yearBrackets(effortList):
    '''Convert a list of years to a bracketed list of groups.

      [ effortList is a list of Effort instances ->
          return a string of the form "[G0,G1,...]" such that
          each group Gi is a single year ("YYY"), bracketed range of
          years ("YYY-YYY"), or multiply-counted group ("YYY (N)") ]
    #-- 1
    # [ resultList  :=  a new, empty list
    #   numberList  :=  list of the year numbers in effortList as ints ]
    resultList = []
    numberList = [ int(effort.year_no)
                   for effort in effortList ]

For the logical that forms the list of (year_no, count) tuples, see Section 25, “countValues(): Summarize a list of years”.
    #-- 2
    # [ pairList  :=  a list of pairs (value, count) representing
    #       numberList ]
    pairList = countValues(numberList)

Each call to Section 26, “peelGroup(): Find the first date group in a list” removes one or more rows from the front of pairList and returns the equivalent character form.
    #-- 3
    # [ pairList  :=  empty
    #   resultList  +:=  strings representing the sequences,
    #       repeated value groups, and single values in pairList ]
    while len(pairList) > 0:
        #-- 3 body
        # [ pairList  :=  pairList with the initial sequence,
        #       repeated value group, or single value removed
        #   resultList  :=  string representing the removed group ]
        resultList.append ( peelGroup ( pairList ) )

    #-- 4
    # [ return the concatenated, comma-separated elements of resultList
    #       wrapped in a pair of square brackets ]
    return ("[%s]" % ','.join(resultList))