#!/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)