oval_graph.oval_tree.oval_result   B
last analyzed

Complexity

Total Complexity 45

Size/Duplication

Total Lines 278
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

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

14 Methods

Rating   Name   Duplication   Size   Complexity  
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._one_is_noteval() 0 19 1
A OvalResult.is_notapp_result() 0 14 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._error_unknown_noteval_eq_zero() 0 5 1
A OvalResult._unknown_noteval_notappl_ge_zero() 0 5 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 1
            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 1
        out_result = None
55 1
        if self._one_is_true():
56 1
            out_result = 'true'
57 1
        elif self._one_is_false():
58 1
            out_result = 'false'
59 1
        elif self._one_is_error():
60 1
            out_result = 'error'
61 1
        elif self._one_is_unknown():
62 1
            out_result = 'unknown'
63 1
        elif self._one_is_noteval():
64 1
            out_result = 'noteval'
65 1
        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 1
        true_lt_two = self.number_of_true < 2
74
75 1
        false_ge_zero = self.number_of_false >= 0
76 1
        notappl_ge_zero = self.number_of_notappl >= 0
77
78 1
        noteval_ge_one = self.number_of_noteval >= 1
79
80 1
        error_eq_zero = self.number_of_error == 0
81 1
        unknown_eq_zero = self.number_of_unknown == 0
82
83 1
        false_notappl_ge_zero = false_ge_zero and notappl_ge_zero
84 1
        error_unknown_eq_zero = error_eq_zero and unknown_eq_zero
85 1
        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 1
        true_lt_two = self.number_of_true < 2
94
95 1
        false_ge_zero = self.number_of_false >= 0
96 1
        notappl_ge_zero = self.number_of_notappl >= 0
97 1
        noteval_ge_zero = self.number_of_noteval >= 0
98
99 1
        error_eq_zero = self.number_of_error == 0
100
101 1
        unknown_ge_one = self.number_of_unknown >= 1
102
103 1
        false_notappl_noteval_ge_zero = false_ge_zero and notappl_ge_zero and noteval_ge_zero
104 1
        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 1
        true_lt_two = self.number_of_true < 2
113
114 1
        false_ge_zero = self.number_of_false >= 0
115
116 1
        error_ge_one = self.number_of_error >= 1
117
118 1
        unknown_noteval_notappl_ge_zero = self._unknown_noteval_notappl_ge_zero()
119 1
        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 1
        true_ge_two = self.number_of_true >= 2
131 1
        false_ge_zero = self.number_of_false >= 0
132 1
        error_ge_zero = self.number_of_error >= 0
133 1
        unknown_noteval_notappl_ge_zero = self._unknown_noteval_notappl_ge_zero()
134
135 1
        false_error_ge_zero = false_ge_zero and error_ge_zero
136
137 1
        first_case = true_ge_two and false_error_ge_zero and unknown_noteval_notappl_ge_zero
138
139
        # The second case for false
140 1
        true_eq_zero = self.number_of_true == 0
141 1
        false_ge_one = self.number_of_false >= 1
142 1
        notappl_ge_zero = self.number_of_notappl >= 0
143 1
        error_unknown_noteval_eq_zero = self._error_unknown_noteval_eq_zero()
144
145 1
        true_error_unknown_noteval_eq_zero = true_eq_zero and error_unknown_noteval_eq_zero
146
147 1
        second_case = true_error_unknown_noteval_eq_zero and false_ge_one and notappl_ge_zero
148
149 1
        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 1
        true_eq_one = self.number_of_true == 1
159 1
        false_ge_zero = self.number_of_false >= 0
160 1
        notappl_ge_zero = self.number_of_notappl >= 0
161 1
        error_unknown_noteval_eq_zero = self._error_unknown_noteval_eq_zero()
162
163 1
        false_notappl_ge_zero = false_ge_zero and notappl_ge_zero
164 1
        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 1
            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 1
        out_result = None
207 1
        error_eq_zero = self.number_of_error == 0
208 1
        unknown_eq_zero = self.number_of_unknown == 0
209 1
        is_number_of_true_even = (self.number_of_true % 2) == 0
210 1
        if not is_number_of_true_even and self._error_unknown_noteval_eq_zero():
211 1
            out_result = 'true'
212 1
        elif is_number_of_true_even and self._error_unknown_noteval_eq_zero():
213 1
            out_result = 'false'
214 1
        elif self.number_of_error >= 1:
215 1
            out_result = 'error'
216 1
        elif error_eq_zero and self.number_of_unknown >= 1:
217 1
            out_result = 'unknown'
218 1
        elif error_eq_zero and unknown_eq_zero and self.number_of_noteval >= 1:
219 1
            out_result = 'noteval'
220 1
        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 1
        out_result = None
237 1
        bool_eq_zero = self.number_of_false == 0 if operator == 'and' else self.number_of_true == 0
238 1
        if bool_eq_zero and self.number_of_error >= 1:
239 1
            out_result = 'error'
240 1
        elif bool_eq_zero and self.number_of_error == 0 and self.number_of_unknown >= 1:
241 1
            out_result = 'unknown'
242 1
        elif bool_eq_zero and self._error_unknown_eq_zero_and_noteval_ge_one():
243 1
            out_result = 'noteval'
244 1
        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 1
        error_eq_zero = self.number_of_error == 0
254 1
        unknown_eq_zero = self.number_of_unknown == 0
255 1
        noteval_ge_one = self.number_of_noteval >= 1
256 1
        return error_eq_zero and unknown_eq_zero and noteval_ge_one
257
258 1
    def _unknown_noteval_notappl_ge_zero(self):
259 1
        unknown_ge_zero = self.number_of_unknown >= 0
260 1
        noteval_ge_zero = self.number_of_noteval >= 0
261 1
        notappl_ge_zero = self.number_of_notappl >= 0
262 1
        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