Coverage for src/bob/pipelines/utils.py: 65%

54 statements  

« prev     ^ index     » next       coverage.py v7.6.0, created at 2024-07-12 21:32 +0200

1import copy 

2import pickle 

3 

4import numpy as np 

5 

6 

7def is_picklable(obj): 

8 """Test if an object is picklable or not.""" 

9 try: 

10 pickle.dumps(obj) 

11 except TypeError: 

12 return False 

13 except pickle.PicklingError: 

14 return False 

15 

16 return True 

17 

18 

19def assert_picklable(obj): 

20 """Test if an object is picklable or not.""" 

21 

22 string = pickle.dumps(obj) 

23 new_obj = pickle.loads(string) 

24 obj = obj.__dict__ 

25 new_obj = new_obj.__dict__ 

26 assert len(obj) == len(new_obj) 

27 assert list(obj.keys()) == list(new_obj.keys()) 

28 for k, v in obj.items(): 

29 if isinstance(v, np.ndarray): 

30 np.testing.assert_equal(v, new_obj[k]) 

31 else: 

32 assert v == new_obj[k] 

33 

34 

35def hash_string(key, bucket_size=1000): 

36 """ 

37 Generates a hash code given a string. 

38 The have is given by the `sum(ord([string])) mod bucket_size` 

39 

40 Parameters 

41 ---------- 

42 

43 key: str 

44 Input string to be hashed 

45 

46 bucket_size: int 

47 Size of the hash table. 

48 

49 """ 

50 return str(sum([ord(i) for i in (key)]) % bucket_size) 

51 

52 

53def flatten_samplesets(samplesets): 

54 """ 

55 Takes a list of SampleSets (with one or multiple samples in each SampleSet) 

56 and returns a list of SampleSets (with one sample in each SampleSet) 

57 

58 Parameters 

59 ---------- 

60 

61 samplesets: list of :obj:`bob.pipelines.SampleSet` 

62 Input list of SampleSets (with one or multiple samples in each SampleSet 

63 

64 """ 

65 new_samplesets = [] 

66 

67 # Iterating over the samplesets 

68 for sset in samplesets: 

69 # Iterating over the samples, and deep copying each sampleset 

70 # for each sample 

71 for i, s in enumerate(sset): 

72 new_sset = copy.deepcopy(sset) 

73 new_sset.samples = [s] 

74 # Very important step 

75 # We need to redo the keys 

76 new_sset.key = f"{new_sset.key}-{i}" 

77 

78 new_samplesets.append(new_sset) 

79 

80 return new_samplesets 

81 

82 

83def check_parameters_for_validity( 

84 parameters, parameter_description, valid_parameters, default_parameters=None 

85): 

86 """Checks the given parameters for validity. 

87 

88 Checks a given parameter is in the set of valid parameters. It also 

89 assures that the returned parameters form a list. If parameters is 

90 'None' or empty, the default_parameters will be returned (if 

91 default_parameters is omitted, all valid_parameters are returned). 

92 

93 This function will return a list of parameters, or raise a 

94 ValueError. 

95 

96 

97 Parameters 

98 ---------- 

99 parameters : str or list of :obj:`str` or None 

100 The parameters to be checked. Might be a string, a list/tuple of 

101 strings, or None. 

102 

103 parameter_description : str 

104 A short description of the parameter. This will be used to raise an 

105 exception in case the parameter is not valid. 

106 

107 valid_parameters : list of :obj:`str` 

108 A list/tuple of valid values for the parameters. 

109 

110 default_parameters : list of :obj:`str` or None 

111 The list/tuple of default parameters that will be returned in case 

112 parameters is None or empty. If omitted, all valid_parameters are used. 

113 

114 Returns 

115 ------- 

116 list 

117 A list containing the valid parameters. 

118 

119 Raises 

120 ------ 

121 ValueError 

122 If some of the parameters are not valid. 

123 

124 """ 

125 

126 if not parameters: 

127 # parameters are not specified, i.e., 'None' or empty lists 

128 parameters = ( 

129 default_parameters 

130 if default_parameters is not None 

131 else valid_parameters 

132 ) 

133 

134 if not isinstance(parameters, (list, tuple, set)): 

135 # parameter is just a single element, not a tuple or list -> transform it 

136 # into a tuple 

137 parameters = (parameters,) 

138 

139 # perform the checks 

140 for parameter in parameters: 

141 if parameter not in valid_parameters: 

142 raise ValueError( 

143 "Invalid %s '%s'. Valid values are %s, or lists/tuples of those" 

144 % (parameter_description, parameter, valid_parameters) 

145 ) 

146 

147 # check passed, now return the list of parameters 

148 return list(parameters) 

149 

150 

151def check_parameter_for_validity( 

152 parameter, parameter_description, valid_parameters, default_parameter=None 

153): 

154 """Checks the given parameter for validity 

155 

156 Ensures a given parameter is in the set of valid parameters. If the 

157 parameter is ``None`` or empty, the value in ``default_parameter`` will 

158 be returned, in case it is specified, otherwise a :py:exc:`ValueError` 

159 will be raised. 

160 

161 This function will return the parameter after the check tuple or list 

162 of parameters, or raise a :py:exc:`ValueError`. 

163 

164 Parameters 

165 ---------- 

166 parameter : :obj:`str` or :obj:`None` 

167 The single parameter to be checked. Might be a string or None. 

168 

169 parameter_description : str 

170 A short description of the parameter. This will be used to raise an 

171 exception in case the parameter is not valid. 

172 

173 valid_parameters : list of :obj:`str` 

174 A list/tuple of valid values for the parameters. 

175 

176 default_parameter : list of :obj:`str`, optional 

177 The default parameter that will be returned in case parameter is None or 

178 empty. If omitted and parameter is empty, a ValueError is raised. 

179 

180 Returns 

181 ------- 

182 str 

183 The validated parameter. 

184 

185 Raises 

186 ------ 

187 ValueError 

188 If the specified parameter is invalid. 

189 

190 """ 

191 

192 if parameter is None: 

193 # parameter not specified ... 

194 if default_parameter is not None: 

195 # ... -> use default parameter 

196 parameter = default_parameter 

197 else: 

198 # ... -> raise an exception 

199 raise ValueError( 

200 "The %s has to be one of %s, it might not be 'None'." 

201 % (parameter_description, valid_parameters) 

202 ) 

203 

204 if isinstance(parameter, (list, tuple, set)): 

205 # the parameter is in a list/tuple ... 

206 if len(parameter) > 1: 

207 raise ValueError( 

208 "The %s has to be one of %s, it might not be more than one " 

209 "(%s was given)." 

210 % (parameter_description, valid_parameters, parameter) 

211 ) 

212 # ... -> we take the first one 

213 parameter = parameter[0] 

214 

215 # perform the check 

216 if parameter not in valid_parameters: 

217 raise ValueError( 

218 "The given %s '%s' is not allowed. Please choose one of %s." 

219 % (parameter_description, parameter, valid_parameters) 

220 ) 

221 

222 # tests passed -> return the parameter 

223 return parameter