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

1from __future__ import annotations 

2import random 

3from typing import Optional 

4 

5 

6class Classification(object): 

7 """ 

8 Simple class to store the name and color of a classification. 

9 """ 

10 

11 _cached_classifications = {} 

12 

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 ) 

22 

23 @property 

24 def name(self) -> str: 

25 """ 

26 The name of the classification. 

27 """ 

28 return self._name 

29 

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 

36 

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. 

43 

44 If no classification with the provided name is present in the cache, a 

45 new classification is created and the cache is updated. 

46 

47 This is useful if you want to avoid creating multiple classifications with the 

48 same name and use only one instead. 

49 

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 

60 

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 

66 

67 def __str__(self): 

68 return f"Classification {self._name} of color {self._color}" 

69 

70 def __repr__(self): 

71 return f"Classification('{self._name}', {self._color})" 

72 

73 def __eq__(self, other): 

74 if isinstance(other, Classification): 

75 return self._name == other._name and self._color == other._color 

76 return False 

77 

78 def __hash__(self): 

79 return hash(self._name)