docs: def from_words(cls, words, prefix=0, flatten=False):
          """
          Given an iterable of words, return the corresponding table.
          The table is built by accumulating, for each word, for each sub-word,
          the number of occurrences of the corresponding next character.
          
          :param words: an iterable of strings made of alphabetic characters;
          :param prefix: if greater than 0, the maximum length of the prefix to
                         store in the table;
          :param flatten: whether to flatten the table or not;
          :return: the corresponding table.
          
          Example:
          >>> Table.from_words(['abaq'])
          {'a':{'b': 1, 'q': 1}, 'ab': {'a': 1}, 'aba': {'q': 1}, 'b': {'a': 1},
           'ba': {'q': 1}}
          """
          table = defaultdict(lambda: defaultdict(int))
          for word in words:
              word = ">" + word + "<"
              for start in range(len(word) - 1):
                  max_end = ((len(word) - 1) if prefix <= 0
                             else (min(start + prefix + 1, len(word) - 1)))
                  for end in range(start + 1, max_end + 1):
                      sub_word = word[start:end]
                      weight = 1 if flatten else (table[sub_word][word[end]] + 1)
                      table[sub_word][word[end]] = weight
          for k, v in table.items():
              table[k] = dict(v)
          return cls(dict(table))