Coverage for src/sensai/util/helper.py: 82%

28 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-08-13 22:17 +0000

1""" 

2This module contains various helper functions. 

3""" 

4import math 

5from typing import Any, Sequence, Union, TypeVar, List 

6 

7T = TypeVar("T") 

8 

9 

10def count_none(*args: Any) -> int: 

11 """ 

12 Counts the number of arguments that are None 

13 

14 :param args: various arguments 

15 :return: the number of arguments that are None 

16 """ 

17 c = 0 

18 for a in args: 

19 if a is None: 

20 c += 1 

21 return c 

22 

23 

24def count_not_none(*args: Any) -> int: 

25 """ 

26 Counts the number of arguments that are not None 

27 

28 :param args: various arguments 

29 :return: the number of arguments that are not None 

30 """ 

31 return len(args) - count_none(*args) 

32 

33 

34def any_none(*args: Any) -> bool: 

35 """ 

36 :param args: various arguments 

37 :return: True if any of the arguments are None, False otherwise 

38 """ 

39 return count_none(*args) > 0 

40 

41 

42def all_none(*args: Any) -> bool: 

43 """ 

44 :param args: various arguments 

45 :return: True if all of the arguments are None, False otherwise 

46 """ 

47 return count_none(*args) == len(args) 

48 

49 

50def check_not_nan_dict(d: dict): 

51 """ 

52 Raises ValueError if any of the values in the given dictionary are NaN, reporting the respective keys 

53 

54 :param d: a dictionary mapping to floats that are to be checked for NaN 

55 """ 

56 invalid_keys = [k for k, v in d.items() if math.isnan(v)] 

57 if len(invalid_keys) > 0: 

58 raise ValueError(f"Got one or more NaN values: {invalid_keys}") 

59 

60 

61# noinspection PyUnusedLocal 

62def mark_used(*args): 

63 """ 

64 Utility function to mark identifiers as used. 

65 The function does nothing. 

66 

67 :param args: pass identifiers that shall be marked as used here 

68 """ 

69 pass 

70 

71 

72def flatten_arguments(args: Sequence[Union[T, Sequence[T]]]) -> List[T]: 

73 """ 

74 Main use case is to support both interfaces of the type f(T1, T2, ...) and f([T1, T2, ...]) simultaneously. 

75 It is assumed that if the latter form is passed, the arguments are either in a list or a tuple. Moreover, 

76 T cannot be a tuple or a list itself. 

77 

78 Overall this function is not all too safe and one should be aware of what one is doing when using it 

79 """ 

80 result = [] 

81 for arg in args: 

82 if isinstance(arg, list) or isinstance(arg, tuple): 

83 result.extend(arg) 

84 else: 

85 result.append(arg) 

86 return result