# - - - P u z z l e . _ _ m a t c h L e n g t h s
def __matchLengths ( self ):
'''See if the word lengths match the slot lengths.
[ (self.__slotMap contains a set of slots) and
(self.__wordMap contains a set of words) ->
if (the counts of slots of each length in self.__slotMap
do not exactly match the counts of words of each length
in self.__wordBank) ->
raise SyntaxError
else -> I ]
'''
In a properly structured puzzle, there are exactly as many
slots as words; see Section 63, “WordBank.__len__(): How many total
words?”.
#-- 1 --
# [ if the number of words in self is the same as the
# number of slots in self ->
# I
# else -> raise SyntaxError ]
if len(self.__slotMap) != len(self.__wordBank):
raise SyntaxError ( "This puzzle has %d slots but "
"%d words to go in them." %
(len(self.__slotMap), len(self.__wordBank)) )
Furthermore, for each different word length in the word
list, there must be exactly as many slots of that length as
words of that length. We'll start this by counting the
slots of each length. The expression “defaultdict(int)” returns a new dictionary
in which new entries will automatically default to 0. See
http://docs.python.org/library/collections.html#collections.defaultdict for this container; also see Section 20, “Puzzle.__genSlots(): Detect slots in a
row or column” for the generator that visits
every slot.
#-- 2 --
# [ countByLen := a dictionary whose keys are the
# unique lengths of slots in self, and each
# corresponding value is the number of slots in
# self that have that length ]
countByLen = defaultdict(int)
for slot in self.__slotMap.values():
countByLen[len(slot)] += 1
See Section 60, “class WordBank: The word list and
puzzle state” for the .maxLen attribute that gives the maximum word
length, and the Section 64, “WordBank.wordsOfLen(): How many words
have a given length?” for
the method that returns the number of words of a given
length.
#-- 3 --
# [ if the counts of slots of each length in countByLen
# correspond exactly to the counts of words of each
# length in self.__wordBank ->
# I
# else -> raise SyntaxError ]
for length in range(2, 1+self.__wordBank.maxLen):
nWords = self.__wordBank.wordsOfLen ( length )
nSlots = countByLen[length]
if nWords != nSlots:
raise SyntaxError ( "There are %d words of length %d, "
"but there are %d slots of that length." %
(nWords, length, nSlots) )