Coverage for qubalab/objects/classification.py: 91%
33 statements
« prev ^ index » next coverage.py v7.6.12, created at 2025-10-07 15:29 +0000
« prev ^ index » next coverage.py v7.6.12, created at 2025-10-07 15:29 +0000
1from __future__ import annotations
2import random
3from typing import Optional
6class Classification(object):
7 """
8 Simple class to store the name and color of a classification.
9 """
11 _cached_classifications = {}
13 def __init__(self, name: str, color: Optional[tuple[int, int, int]] = None):
14 """
15 :param name: the name of the classification
16 :param color: the RGB color (each component between 0 and 255) of the classification. Can be None to use a random color
17 """
18 self._name = name
19 self._color = (
20 tuple(random.randint(0, 255) for _ in range(3)) if color is None else color
21 )
23 @property
24 def name(self) -> str:
25 """
26 The name of the classification.
27 """
28 return self._name
30 @property
31 def color(self) -> tuple[int, int, int]:
32 """
33 The color of the classification.
34 """
35 return self._color ## todo: pylance type hints problem
37 @staticmethod
38 def get_cached_classification(
39 name: str, color: Optional[tuple[int, int, int]] = None
40 ) -> Classification:
41 """
42 Return a classification by looking at an internal cache.
44 If no classification with the provided name is present in the cache, a
45 new classification is created and the cache is updated.
47 This is useful if you want to avoid creating multiple classifications with the
48 same name and use only one instead.
50 :param name: the name of the classification (can be None)
51 :param color: the RGB color (each component between 0 and 255) of the classification.
52 Can be None to use a random color. This is only used if the cache doesn't
53 already contain a classification with the provided name
54 :return: a classification with the provided name, but not always with the provided color
55 if a classification with the same name already existed in the cache. If the provided
56 name is None, None is also returned
57 """
58 if name is None:
59 return None
61 classification = Classification._cached_classifications.get(name)
62 if classification is None:
63 classification = Classification(name, color)
64 Classification._cached_classifications[classification.name] = classification
65 return classification
67 def __str__(self):
68 return f"Classification {self._name} of color {self._color}"
70 def __repr__(self):
71 return f"Classification('{self._name}', {self._color})"
73 def __eq__(self, other):
74 if isinstance(other, Classification):
75 return self._name == other._name and self._color == other._color
76 return False
78 def __hash__(self):
79 return hash(self._name)