Passed
Push — master ( 958bc0...1938a8 )
by Jan
05:51 queued 02:21
created

oval_graph.oval_tree.oval_result   B

Complexity

Total Complexity 45

Size/Duplication

Total Lines 278
Duplicated Lines 0 %

Test Coverage

Coverage 35.56%

Importance

Changes 0
Metric Value
eloc 136
dl 0
loc 278
ccs 48
cts 135
cp 0.3556
rs 8.8
c 0
b 0
f 0
wmc 45

14 Methods

Rating   Name   Duplication   Size   Complexity  
A OvalResult.is_notapp_result() 0 14 1
A OvalResult._error_unknown_noteval_eq_zero() 0 5 1
A OvalResult._one_is_false() 0 29 1
A OvalResult.eval_operator_or() 0 25 5
C OvalResult.eval_operator_xor() 0 29 11
A OvalResult._one_is_true() 0 14 1
B OvalResult.eval_operator_one() 0 28 6
A OvalResult.eval_operator_and() 0 25 5
A OvalResult._one_is_error() 0 14 1
A OvalResult._one_is_unknown() 0 18 1
A OvalResult._error_unknown_eq_zero_and_noteval_ge_one() 0 5 1
C OvalResult._eval_error_unknown_noteval_for_operators_and_or() 0 23 9
A OvalResult._unknown_noteval_notappl_ge_zero() 0 5 1
A OvalResult._one_is_noteval() 0 19 1

How to fix   Complexity   

Complexity

Complex classes like oval_graph.oval_tree.oval_result 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 1
from typing import NamedTuple
2
3
4 1
class OvalResult(NamedTuple):
5 1
    number_of_true: int = 0
6 1
    number_of_false: int = 0
7 1
    number_of_error: int = 0
8 1
    number_of_unknown: int = 0
9 1
    number_of_noteval: int = 0
10 1
    number_of_notappl: int = 0
11
12 1
    def eval_operator_and(self):
13
        """
14
        The AND operator produces a true result if every argument is true. If one or more arguments
15
        are false, the result of the AND is false. If one or more of the arguments are unknown, and
16
        if none of the arguments are false, then the AND operator produces a result of unknown.
17
18
        Returns:
19
                str. return values::
20
21
                    true
22
                    false
23
                    error
24
                    unknown
25
                    noteval
26
        """
27 1
        out_result = None
28 1
        false_eq_zero = self.number_of_false == 0
29 1
        true_gt_zero = self.number_of_true > 0
30 1
        if true_gt_zero and false_eq_zero and self._error_unknown_noteval_eq_zero():
31 1
            out_result = 'true'
32 1
        elif self.number_of_false >= 1:
33 1
            out_result = 'false'
34
        else:
35
            out_result = self._eval_error_unknown_noteval_for_operators_and_or('and')
36 1
        return out_result
37
38 1
    def eval_operator_one(self):
39
        """
40
        The ONE operator produces a true result if one and only one argument is true. If there are
41
        more than argument is true (or if there are no true arguments), the result of the ONE
42
        is false. If one or more of the arguments are unknown, then the ONE operator produces
43
        a result of unknown.
44
45
        Returns:
46
            str. return values::
47
48
                true
49
                false
50
                error
51
                unknown
52
                noteval
53
        """
54
        out_result = None
55
        if self._one_is_true():
56
            out_result = 'true'
57
        elif self._one_is_false():
58
            out_result = 'false'
59
        elif self._one_is_error():
60
            out_result = 'error'
61
        elif self._one_is_unknown():
62
            out_result = 'unknown'
63
        elif self._one_is_noteval():
64
            out_result = 'noteval'
65
        return out_result
66
67 1
    def _one_is_noteval(self):
68
        """Evaluates if the result match noteval for one operator.
69
70
        Returns:
71
                bool.
72
        """
73
        true_lt_two = self.number_of_true < 2
74
75
        false_ge_zero = self.number_of_false >= 0
76
        notappl_ge_zero = self.number_of_notappl >= 0
77
78
        noteval_ge_one = self.number_of_noteval >= 1
79
80
        error_eq_zero = self.number_of_error == 0
81
        unknown_eq_zero = self.number_of_unknown == 0
82
83
        false_notappl_ge_zero = false_ge_zero and notappl_ge_zero
84
        error_unknown_eq_zero = error_eq_zero and unknown_eq_zero
85
        return true_lt_two and false_notappl_ge_zero and noteval_ge_one and error_unknown_eq_zero
86
87 1
    def _one_is_unknown(self):
88
        """Evaluates if the result match unknown for one operator.
89
90
        Returns:
91
                bool.
92
        """
93
        true_lt_two = self.number_of_true < 2
94
95
        false_ge_zero = self.number_of_false >= 0
96
        notappl_ge_zero = self.number_of_notappl >= 0
97
        noteval_ge_zero = self.number_of_noteval >= 0
98
99
        error_eq_zero = self.number_of_error == 0
100
101
        unknown_ge_one = self.number_of_unknown >= 1
102
103
        false_notappl_noteval_ge_zero = false_ge_zero and notappl_ge_zero and noteval_ge_zero
104
        return true_lt_two and false_notappl_noteval_ge_zero and error_eq_zero and unknown_ge_one
105
106 1
    def _one_is_error(self):
107
        """Evaluates if the result match unknown for one operator.
108
109
        Returns:
110
                bool.
111
        """
112
        true_lt_two = self.number_of_true < 2
113
114
        false_ge_zero = self.number_of_false >= 0
115
116
        error_ge_one = self.number_of_error >= 1
117
118
        unknown_noteval_notappl_ge_zero = self._unknown_noteval_notappl_ge_zero()
119
        return true_lt_two and false_ge_zero and error_ge_one and unknown_noteval_notappl_ge_zero
120
121 1
    def _one_is_false(self):
122
        """
123
        Evaluates if the result match false for one operator.
124
        Operator ONE has two cases of false state.
125
126
        Returns:
127
                bool.
128
        """
129
        # The first case for false
130
        true_ge_two = self.number_of_true >= 2
131
        false_ge_zero = self.number_of_false >= 0
132
        error_ge_zero = self.number_of_error >= 0
133
        unknown_noteval_notappl_ge_zero = self._unknown_noteval_notappl_ge_zero()
134
135
        false_error_ge_zero = false_ge_zero and error_ge_zero
136
137
        first_case = true_ge_two and false_error_ge_zero and unknown_noteval_notappl_ge_zero
138
139
        # The second case for false
140
        true_eq_zero = self.number_of_true == 0
141
        false_ge_one = self.number_of_false >= 1
142
        notappl_ge_zero = self.number_of_notappl >= 0
143
        error_unknown_noteval_eq_zero = self._error_unknown_noteval_eq_zero()
144
145
        true_error_unknown_noteval_eq_zero = true_eq_zero and error_unknown_noteval_eq_zero
146
147
        second_case = true_error_unknown_noteval_eq_zero and false_ge_one and notappl_ge_zero
148
149
        return first_case or second_case
150
151 1
    def _one_is_true(self):
152
        """
153
        Evaluates if the result match true for one operator.
154
155
        Returns:
156
                bool.
157
        """
158
        true_eq_one = self.number_of_true == 1
159
        false_ge_zero = self.number_of_false >= 0
160
        notappl_ge_zero = self.number_of_notappl >= 0
161
        error_unknown_noteval_eq_zero = self._error_unknown_noteval_eq_zero()
162
163
        false_notappl_ge_zero = false_ge_zero and notappl_ge_zero
164
        return true_eq_one and error_unknown_noteval_eq_zero and false_notappl_ge_zero
165
166 1
    def eval_operator_or(self):
167
        """
168
        The OR operator produces a true result if one or more arguments is true. If every argument
169
        is false, the result of the OR is false. If one or more of the arguments are unknown and
170
        if none of arguments are true, then the OR operator produces a result of unknown.
171
172
        Returns:
173
            str. return values::
174
175
                true
176
                false
177
                error
178
                unknown
179
                noteval
180
        """
181 1
        out_result = None
182 1
        true_eq_zero = self.number_of_true == 0
183 1
        false_ge_one = self.number_of_false >= 1
184 1
        if self.number_of_true >= 1:
185 1
            out_result = 'true'
186 1
        elif true_eq_zero and false_ge_one and self._error_unknown_noteval_eq_zero():
187 1
            out_result = 'false'
188
        else:
189
            out_result = self._eval_error_unknown_noteval_for_operators_and_or('or')
190 1
        return out_result
191
192 1
    def eval_operator_xor(self):
193
        """
194
        XOR is defined to be true if an odd number of its arguments are true, and false otherwise.
195
        If any of the arguments are unknown, then the XOR operator produces a result of unknown.
196
197
        Returns:
198
            str. return values::
199
200
                true
201
                false
202
                error
203
                unknown
204
                noteval
205
        """
206
        out_result = None
207
        error_eq_zero = self.number_of_error == 0
208
        unknown_eq_zero = self.number_of_unknown == 0
209
        is_number_of_true_even = (self.number_of_true % 2) == 0
210
        if not is_number_of_true_even and self._error_unknown_noteval_eq_zero():
211
            out_result = 'true'
212
        elif is_number_of_true_even and self._error_unknown_noteval_eq_zero():
213
            out_result = 'false'
214
        elif self.number_of_error >= 1:
215
            out_result = 'error'
216
        elif error_eq_zero and self.number_of_unknown >= 1:
217
            out_result = 'unknown'
218
        elif error_eq_zero and unknown_eq_zero and self.number_of_noteval >= 1:
219
            out_result = 'noteval'
220
        return out_result
221
222 1
    def _eval_error_unknown_noteval_for_operators_and_or(self, operator):
223
        """
224
        Evaluates if the operator result match the values for error, unknown, noteval.
225
226
        Args:
227
            operator (str): Specifies for which operator is used
228
229
        Returns:
230
            str or None. return values::
231
232
                error
233
                unknown
234
                noteval
235
        """
236
        out_result = None
237
        bool_eq_zero = self.number_of_false == 0 if operator == 'and' else self.number_of_true == 0
238
        if bool_eq_zero and self.number_of_error >= 1:
239
            out_result = 'error'
240
        elif bool_eq_zero and self.number_of_error == 0 and self.number_of_unknown >= 1:
241
            out_result = 'unknown'
242
        elif bool_eq_zero and self._error_unknown_eq_zero_and_noteval_ge_one():
243
            out_result = 'noteval'
244
        return out_result
245
246 1
    def _error_unknown_noteval_eq_zero(self):
247 1
        error_eq_zero = self.number_of_error == 0
248 1
        unknown_eq_zero = self.number_of_unknown == 0
249 1
        noteval_eq_zero = self.number_of_noteval == 0
250 1
        return error_eq_zero and unknown_eq_zero and noteval_eq_zero
251
252 1
    def _error_unknown_eq_zero_and_noteval_ge_one(self):
253
        error_eq_zero = self.number_of_error == 0
254
        unknown_eq_zero = self.number_of_unknown == 0
255
        noteval_ge_one = self.number_of_noteval >= 1
256
        return error_eq_zero and unknown_eq_zero and noteval_ge_one
257
258 1
    def _unknown_noteval_notappl_ge_zero(self):
259
        unknown_ge_zero = self.number_of_unknown >= 0
260
        noteval_ge_zero = self.number_of_noteval >= 0
261
        notappl_ge_zero = self.number_of_notappl >= 0
262
        return unknown_ge_zero and notappl_ge_zero and noteval_ge_zero
263
264 1
    def is_notapp_result(self):
265
        """
266
        Evaluates if the counts of values in the result matches the notapp result.
267
268
        Returns:
269
            bool.
270
        """
271 1
        notappl_gt_zero = self.number_of_notappl > 0
272 1
        false_eq_zero = self.number_of_false == 0
273 1
        true_eq_zero = self.number_of_true == 0
274 1
        error_unknown_noteval_eq_zero = self._error_unknown_noteval_eq_zero()
275
276 1
        true_false_eq_zero = false_eq_zero and true_eq_zero
277
        return notappl_gt_zero and true_false_eq_zero and error_unknown_noteval_eq_zero
278