Passed
Pull Request — master (#173)
by Jan
04:08
created

oval_graph.oval_tree.evaluate   C

Complexity

Total Complexity 54

Size/Duplication

Total Lines 421
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 54
eloc 134
dl 0
loc 421
ccs 133
cts 133
cp 1
rs 6.4799
c 0
b 0
f 0

23 Functions

Rating   Name   Duplication   Size   Complexity  
B oval_operator_one() 0 31 7
A one_is_true() 0 13 1
A one_is_false() 0 14 1
A one_is_error() 0 14 1
A one_is_unknown() 0 15 1
A eq_zero_unknown_noteval_notappl() 0 14 1
A error_unknown_eq_noteval_greater_zero() 0 14 1
A error_unknown_noteval_eq_zero() 0 14 1
C oval_operator_xor() 0 30 11
A is_notapp_result() 0 15 1
A oval_operator_or() 0 27 5
A oval_operator_and() 0 27 5
A eq_zero_duo() 0 12 1
A eq_or_greater_zero_duo() 0 12 1
A error_unknown_eq_zero() 0 11 1
A eq_or_greater_zero() 0 11 1
A greater_zero() 0 11 1
A eq_zero() 0 11 1
A smaller_than_two() 0 11 1
A one_is_noteval() 0 14 1
B error_unknown_noteval_for_operators_and_or() 0 23 8
A eq_or_greater_zero_unknown_noteval_notappl() 0 14 1
A one_is_false1() 0 13 1

How to fix   Complexity   

Complexity

Complex classes like oval_graph.oval_tree.evaluate often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
"""
2
    Function for evaluate OVAL operators.
3
"""
4
5
6 1
def oval_operator_and(result):
7
    """The AND operator produces a true result if every argument is true. If one or more arguments
8
       are false, the result of the AND is false. If one or more of the arguments are unknown, and
9
       if none of the arguments are false, then the AND operator produces a result of unknown.
10
11
    Args:
12
            result (dict): Dictionary representing frequencies of values
13
14
    Returns:
15
            str. return values::
16
17
                true
18
                false
19
                error
20
                unknown
21
                noteval
22
    """
23 1
    out_result = None
24 1
    eval_eq_zero = eq_zero(result, 'false_cnt')
25 1
    eval_greater_zero = greater_zero(result, 'true_cnt')
26 1
    if eval_eq_zero and eval_greater_zero and error_unknown_noteval_eq_zero(result):
27 1
        out_result = 'true'
28 1
    elif greater_zero(result, 'false_cnt'):
29 1
        out_result = 'false'
30
    else:
31 1
        out_result = error_unknown_noteval_for_operators_and_or(result, 'and')
32 1
    return out_result
33
34
35 1
def oval_operator_one(result):
36
    """The ONE operator produces a true result if one and only one argument is true. If there are
37
       more than argument is true (or if there are no true arguments), the result of the ONE
38
       is false. If one or more of the arguments are unknown, then the ONE operator produces
39
       a result of unknown.
40
41
    Args:
42
            result (dict): Dictionary representing frequencies of values
43
44
    Returns:
45
            str. return values::
46
47
                true
48
                false
49
                error
50
                unknown
51
                noteval
52
    """
53 1
    out_result = None
54 1
    if one_is_true(result):
55 1
        out_result = 'true'
56
    # Operator ONE has two cases of false
57 1
    elif one_is_false(result) or one_is_false1(result):
58 1
        out_result = 'false'
59 1
    elif one_is_error(result):
60 1
        out_result = 'error'
61 1
    elif one_is_unknown(result):
62 1
        out_result = 'unknown'
63 1
    elif one_is_noteval(result):
64 1
        out_result = 'noteval'
65 1
    return out_result
66
67
68 1
def oval_operator_or(result):
69
    """The OR operator produces a true result if one or more arguments is true. If every argument
70
       is false, the result of the OR is false. If one or more of the arguments are unknown and
71
       if none of arguments are true, then the OR operator produces a result of unknown.
72
73
    Args:
74
            result (dict): Dictionary representing frequencies of values
75
76
    Returns:
77
            str. return values::
78
79
                true
80
                false
81
                error
82
                unknown
83
                noteval
84
    """
85 1
    out_result = None
86 1
    eval_eq_zero = eq_zero(result, 'true_cnt')
87 1
    eval_greater_zero = greater_zero(result, 'false_cnt')
88 1
    if greater_zero(result, 'true_cnt'):
89 1
        out_result = 'true'
90 1
    elif eval_eq_zero and eval_greater_zero and error_unknown_noteval_eq_zero(result):
91 1
        out_result = 'false'
92
    else:
93 1
        out_result = error_unknown_noteval_for_operators_and_or(result, 'or')
94 1
    return out_result
95
96
97 1
def oval_operator_xor(result):
98
    """XOR is defined to be true if an odd number of its arguments are true, and false otherwise.
99
       If any of the arguments are unknown, then the XOR operator produces a result of unknown.
100
101
    Args:
102
            result (dict): Dictionary representing frequencies of values
103
104
    Returns:
105
            str. return values::
106
107
                true
108
                false
109
                error
110
                unknown
111
                noteval
112
    """
113 1
    out_result = None
114 1
    eval_error_cnt = eq_zero(result, 'error_cnt')
115 1
    eval_unknown_cnt = eq_zero(result, 'unknown_cnt')
116 1
    if (result['true_cnt'] % 2) == 1 and eq_zero_unknown_noteval_notappl(result):
117 1
        out_result = 'true'
118 1
    elif (result['true_cnt'] % 2) == 0 and eq_zero_unknown_noteval_notappl(result):
119 1
        out_result = 'false'
120 1
    elif greater_zero(result, 'error_cnt'):
121 1
        out_result = 'error'
122 1
    elif eq_zero(result, 'error_cnt') and greater_zero(result, 'unknown_cnt'):
123 1
        out_result = 'unknown'
124 1
    elif eval_error_cnt and eval_unknown_cnt and greater_zero(result, 'noteval_cnt'):
125 1
        out_result = 'noteval'
126 1
    return out_result
127
128
129 1
def error_unknown_noteval_for_operators_and_or(result, operator):
0 ignored issues
show
Coding Style Naming introduced by
Function name "error_unknown_noteval_for_operators_and_or" doesn't conform to '[a-z_][a-z0-9_]2,30$' pattern ('[a-z_][a-z0-9_]2,30$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
130
    """Evaluates if the result match the values for error, unknown, noteval.
131
132
    Args:
133
            result (dict): Dictionary representing frequencies of values
134
            operator (str): Specifies for which operator is used
135
136
    Returns:
137
            str or None. return values::
138
139
                error
140
                unknown
141
                notappl
142
    """
143 1
    out_result = None
144 1
    value_for_check = 'false_cnt' if operator == 'and' else 'true_cnt'
145 1
    if eq_zero(result, value_for_check) and greater_zero(result, 'error_cnt'):
146 1
        out_result = 'error'
147 1
    elif eq_zero(result, value_for_check) and error_unknown_eq_zero(result):
148 1
        out_result = 'unknown'
149 1
    elif eq_zero(result, value_for_check) and error_unknown_eq_noteval_greater_zero(result):
150 1
        out_result = 'noteval'
151 1
    return out_result
152
153
154 1
def eq_zero(result, cnt):
155
    """Evaluates if the value in the result is equal zero.
156
157
    Args:
158
            result (dict): Dictionary representing frequencies of values
159
            cnt (str): key for value in result
160
161
    Returns:
162
            bool.
163
    """
164 1
    return result[cnt] == 0
165
166
167 1
def eq_zero_duo(result, cnt0, cnt1):
168
    """Evaluates if the two values in the result is equal zero.
169
170
    Args:
171
            result (dict): Dictionary representing frequencies of values
172
            cnt0 (str): key for value in result
173
            cnt1 (str): key for value in result
174
175
    Returns:
176
            bool.
177
    """
178 1
    return result[cnt0] == 0 and result[cnt1] == 0
179
180
181 1
def greater_zero(result, cnt):
182
    """Evaluates if the value in the result is greater then zero.
183
184
    Args:
185
            result (dict): Dictionary representing frequencies of values
186
            cnt (str): key for value in result
187
188
    Returns:
189
            bool.
190
    """
191 1
    return result[cnt] > 0
192
193
194 1
def eq_or_greater_zero(result, cnt):
195
    """Evaluates if the value in the result is greater or equal zero.
196
197
    Args:
198
            result (dict): Dictionary representing frequencies of values
199
            cnt (str): key for value in result
200
201
    Returns:
202
            bool.
203
    """
204 1
    return result[cnt] >= 0
205
206
207 1
def eq_or_greater_zero_duo(result, cnt0, cnt1):
208
    """Evaluates if the two values in the result is greater or equal zero.
209
210
    Args:
211
            result (dict): Dictionary representing frequencies of values
212
            cnt0 (str): key for value in result
213
            cnt1 (str): key for value in result
214
215
    Returns:
216
            bool.
217
    """
218 1
    return result[cnt0] >= 0 and result[cnt1] >= 0
219
220
221 1
def smaller_than_two(result, cnt):
222
    """Evaluates if the value in the result is smaller than two.
223
224
    Args:
225
            result (dict): Dictionary representing frequencies of values
226
            cnt (str): key for value in result
227
228
    Returns:
229
            bool.
230
    """
231 1
    return result[cnt] < 2
232
233
234 1
def one_is_noteval(result):
235
    """Evaluates if the result match noteval for one operator.
236
237
    Args:
238
            result (dict): Dictionary representing frequencies of values
239
240
    Returns:
241
            bool.
242
    """
243 1
    true_cnt = smaller_than_two(result, 'true_cnt')
244 1
    false_cnt_notappl_cnt = eq_or_greater_zero_duo(result, 'false_cnt', 'notappl_cnt')
245 1
    error_cnt_unknown_cnt = eq_zero_duo(result, 'error_cnt', 'unknown_cnt')
246 1
    noteval_cnt = greater_zero(result, 'noteval_cnt')
247 1
    return true_cnt and false_cnt_notappl_cnt and error_cnt_unknown_cnt and noteval_cnt
248
249
250 1
def one_is_unknown(result):
251
    """Evaluates if the result match unknown for one operator.
252
253
    Args:
254
            result (dict): Dictionary representing frequencies of values
255
256
    Returns:
257
            bool.
258
    """
259 1
    true_cnt = smaller_than_two(result, 'true_cnt')
260 1
    false_cnt = eq_or_greater_zero(result, 'false_cnt')
261 1
    error_cnt = eq_zero(result, 'error_cnt')
262 1
    unknown_cnt = result['unknown_cnt'] >= 1
263 1
    noteval_cnt_notappl_cnt = eq_or_greater_zero_duo(result, 'noteval_cnt', 'notappl_cnt')
264 1
    return true_cnt and false_cnt and error_cnt and unknown_cnt and noteval_cnt_notappl_cnt
265
266
267 1
def one_is_error(result):
268
    """Evaluates if the result match unknown for one operator.
269
270
    Args:
271
            result (dict): Dictionary representing frequencies of values
272
273
    Returns:
274
            bool.
275
    """
276 1
    true_cnt = smaller_than_two(result, 'true_cnt')
277 1
    false_cnt = eq_or_greater_zero(result, 'false_cnt')
278 1
    error_cnt = greater_zero(result, 'error_cnt')
279 1
    unknown_noteval_notappl = eq_or_greater_zero_unknown_noteval_notappl(result)
280 1
    return true_cnt and false_cnt and error_cnt and unknown_noteval_notappl
281
282
283 1
def one_is_false(result):
284
    """Evaluates if the result match false for one operator.
285
286
    Args:
287
            result (dict): Dictionary representing frequencies of values
288
289
    Returns:
290
            bool.
291
    """
292 1
    true_cnt = eq_zero(result, 'true_cnt')
293 1
    false_cnt = eq_or_greater_zero(result, 'false_cnt')
294 1
    unknown_noteval_cnt = error_unknown_noteval_eq_zero(result)
295 1
    notappl_cnt = result['notappl_cnt'] >= 0
296 1
    return true_cnt and false_cnt and unknown_noteval_cnt and notappl_cnt
297
298
299 1
def one_is_false1(result):
300
    """Evaluates  if the result match false for one operator.
301
302
    Args:
303
            result (dict): Dictionary representing frequencies of values
304
305
    Returns:
306
            bool.
307
    """
308 1
    true_cnt = result['true_cnt'] >= 2
309 1
    false_error_cnt = eq_or_greater_zero_duo(result, 'false_cnt', 'error_cnt')
310 1
    unknown_noteval_notappl = eq_or_greater_zero_unknown_noteval_notappl(result)
311 1
    return true_cnt and false_error_cnt and unknown_noteval_notappl
312
313
314 1
def one_is_true(result):
315
    """Evaluates if the result match true for one operator.
316
317
    Args:
318
            result (dict): Dictionary representing frequencies of values
319
320
    Returns:
321
            bool.
322
    """
323 1
    true_cnt = result['true_cnt'] == 1
324 1
    false_notappl_cnt = eq_or_greater_zero_duo(result, 'false_cnt', 'notappl_cnt')
325 1
    unknown_noteval_cnt = error_unknown_noteval_eq_zero(result)
326 1
    return true_cnt and false_notappl_cnt and unknown_noteval_cnt
327
328
329 1
def eq_or_greater_zero_unknown_noteval_notappl(result):
0 ignored issues
show
Coding Style Naming introduced by
Function name "eq_or_greater_zero_unknown_noteval_notappl" doesn't conform to '[a-z_][a-z0-9_]2,30$' pattern ('[a-z_][a-z0-9_]2,30$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
330
    """Evaluates if counts of values unknown,
331
       noteval and notappl in result are equal or greater zero.
332
333
    Args:
334
            result (dict): Dictionary representing frequencies of values
335
336
    Returns:
337
            bool.
338
    """
339 1
    unknown_cnt = eq_or_greater_zero(result, 'unknown_cnt')
340 1
    noteval_cnt = eq_or_greater_zero(result, 'noteval_cnt')
341 1
    notappl_cnt = eq_or_greater_zero(result, 'notappl_cnt')
342 1
    return unknown_cnt and notappl_cnt and noteval_cnt
343
344
345 1
def eq_zero_unknown_noteval_notappl(result):
346
    """Evaluates if counts of values error,
347
       unknown and noteval in result are equal zero.
348
349
    Args:
350
            result (dict): Dictionary representing frequencies of values
351
352
    Returns:
353
            bool.
354
    """
355 1
    error_cnt = eq_zero(result, 'error_cnt')
356 1
    unknown_cnt = eq_zero(result, 'unknown_cnt')
357 1
    noteval_cnt = eq_zero(result, 'noteval_cnt')
358 1
    return error_cnt and unknown_cnt and noteval_cnt
359
360
361 1
def error_unknown_noteval_eq_zero(result):
362
    """Evaluates if counts of values error,
363
       noteval and unknown in result are equal zero.
364
365
    Args:
366
            result (dict): Dictionary representing frequencies of values
367
368
    Returns:
369
            bool.
370
    """
371 1
    error_cnt = eq_zero(result, 'error_cnt')
372 1
    unknown_cnt = eq_zero(result, 'unknown_cnt')
373 1
    noteval_cnt = eq_zero(result, 'noteval_cnt')
374 1
    return error_cnt and unknown_cnt and noteval_cnt
375
376
377 1
def error_unknown_eq_noteval_greater_zero(result):
0 ignored issues
show
Coding Style Naming introduced by
Function name "error_unknown_eq_noteval_greater_zero" doesn't conform to '[a-z_][a-z0-9_]2,30$' pattern ('[a-z_][a-z0-9_]2,30$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
378
    """Evaluates if counts of values in result for unknown,
379
       error are equal zero and for noteval is greater than zero.
380
381
    Args:
382
            result (dict): Dictionary representing frequencies of values
383
384
    Returns:
385
            bool.
386
    """
387 1
    error_cnt = eq_zero(result, 'error_cnt')
388 1
    unknown_cnt = eq_zero(result, 'unknown_cnt')
389 1
    noteval_cnt = greater_zero(result, 'noteval_cnt')
390 1
    return error_cnt and unknown_cnt and noteval_cnt
391
392
393 1
def error_unknown_eq_zero(result):
394
    """Evaluates if counts of values in result for
395
       error is equal zero and for unknown is greater than zero.
396
397
    Args:
398
            result (dict): Dictionary representing frequencies of values
399
400
    Returns:
401
            bool.
402
    """
403 1
    return eq_zero(result, 'error_cnt') and greater_zero(result, 'unknown_cnt')
404
405
406 1
def is_notapp_result(result):
407
    """Evaluates if the counts of values in
408
       the result matches the notapp result.
409
410
    Args:
411
            result (dict): Dictionary representing frequencies of values
412
413
    Returns:
414
            bool.
415
     """
416 1
    notappl_cnt = result['notappl_cnt'] > 0
417 1
    false_cnt = eq_zero(result, 'false_cnt')
418 1
    unknown_noteval_cnt = error_unknown_noteval_eq_zero(result)
419 1
    true_cnt = eq_zero(result, 'true_cnt')
420
    return notappl_cnt and false_cnt and unknown_noteval_cnt and true_cnt
421