| #!/usr/bin/evn python | 
| from __future__ import annotations | 
|   | 
| from typing import Final, override | 
| import bisect | 
|   | 
|   | 
| filename: Final[str] = "taxonomie.csv" | 
|   | 
|   | 
| class Taxonomy: | 
|     def __init__(self, niveau: int, name: str): | 
|         self._niveau = niveau | 
|         self._name = name | 
|         self._id = (niveau, name) | 
|         self._words = [] | 
|         self._sorted_fmt_words = [] | 
|         self._max_width = 0 | 
|   | 
|     def add(self, word: str): | 
|         if word not in self._words: | 
|             bisect.insort(self._words, word, key=lambda w: w.lower()) | 
|             if (new_width := len(word)) > self._max_width: | 
|                 self._max_width = new_width | 
|   | 
|     def __getitem__(self, item): | 
|         word = self._words[item] if item < len(self._words) else " " | 
|         return word.ljust(self._max_width) | 
|   | 
|     def name(self): | 
|         plain_name = f" {self._name} " | 
|         return plain_name.center(self._max_width, "#") | 
|   | 
|     def __len__(self): | 
|         return len(self._words) | 
|   | 
|     def __contains__(self, item): | 
|         return item in self._words | 
|   | 
|     @override | 
|     def __repr__(self): | 
|         if len(self._words) < 3: | 
|             repr_word = f"{self._words}" | 
|         else: | 
|             chosen_words = [] | 
|             wc = 0 | 
|             before_idx = 3 | 
|             after_idx = len(self._words) - 3 | 
|             for w in self._words: | 
|                 wc += 1 | 
|                 if wc < before_idx or wc > after_idx: | 
|                     chosen_words.append(w) | 
|                 if wc == before_idx: | 
|                     chosen_words.append("...") | 
|             repr_word = f"{chosen_words}" | 
|         return f"{self._id} {repr_word} ({len(self._words)})" | 
|   | 
|     def __gt__(self, other): | 
|         return self._niveau >= other._niveau | 
|   | 
|   | 
| def group_term(line: str, data: dict[str, Taxonomy]) -> None: | 
|     terms = tuple(t.strip() for t in line.split(";")) | 
|     key = (int(terms[1]), terms[2]) | 
|     niveau = data.get(key, Taxonomy(key[0], key[1])) | 
|     niveau.add(terms[0]) | 
|     if key not in data: | 
|         data[key] = niveau | 
|   | 
|   | 
| def print_taxonomy(data: dict[str, Taxonomy]) -> None: | 
|     wc = (len(t) for t in data.values() ) | 
|     longest_taxonomie = max(wc) | 
|     taxonomie = sorted(data.values()) | 
|     names = [t.name() for t in taxonomie] | 
|     sep_str = " ; " | 
|     print(sep_str.join(names)) | 
|     for i in range(0, longest_taxonomie): | 
|         terms = [] | 
|         for t in taxonomie: | 
|             terms.append(t[i]) | 
|         print(sep_str.join(terms)) | 
|   | 
|   | 
|   | 
|   | 
| if __name__ == "__main__": | 
|     terms = {} | 
|     with open(filename) as file: | 
|         for line in file: | 
|             group_term(line, terms) | 
|   | 
|     print_taxonomy(terms) |