test_express_delivery.Tests.check_solution()   F
last analyzed

Complexity

Conditions 16

Size

Total Lines 42
Code Lines 39

Duplication

Lines 14
Ratio 33.33 %

Importance

Changes 0
Metric Value
cc 16
eloc 39
nop 4
dl 14
loc 42
rs 2.4
c 0
b 0
f 0

How to fix   Complexity   

Complexity

Complex classes like test_express_delivery.Tests.check_solution() 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
import unittest
2
3
from express_delivery import checkio
4
5
6
class Tests(unittest.TestCase):
7
    TESTS = {
8
        "1. Basics": [
9
            {
10
                "input": ["S...", "....", "B.WB", "..WE"],
11
                "answer": (["S...", "....", "B.WB", "..WE"], 12),
12
                "explanation": "LLLDDD",
13
            },
14
            {
15
                "input": ["S...", "....", "B..B", "..WE"],
16
                "answer": (["S...", "....", "B..B", "..WE"], 11),
17
                "explanation": "DDBLLLBD",
18
            },
19
        ],
20
        "2. Extra": [
21
            {
22
                "input": ["S.W...", "..WB..", "..WW..", "....B.", "....W.", "..B.BE"],
23
                "answer": (
24
                    ["S.W...", "..WB..", "..WW..", "....B.", "....W.", "..B.BE"],
25
                    20,
26
                ),
27
                "explanation": "",
28
            },
29
            {
30
                "input": ["SBW...", ".WWB..", "..WW..", "......", "...WW.", "..BWBE"],
31
                "answer": (
32
                    ["SBW...", ".WWB..", "..WW..", "......", "...WW.", "..BWBE"],
33
                    18,
34
                ),
35
            },
36
            {
37
                "input": ["S..BW.", ".WWWWW", ".W....", ".W.W.B", ".W.W..", "...W.E"],
38
                "answer": (
39
                    ["S..BW.", ".WWWWW", ".W....", ".W.W.B", ".W.W..", "...W.E"],
40
                    29,
41
                ),
42
            },
43
        ],
44
        "3. Weird": [
45
            {"input": ["SB....BE"], "answer": (["SB....BE"], 11)},
46
            {"input": ["S...BB..E"], "answer": (["S...BB..E"], 16)},
47
            {
48
                "input": ["SBBBBB", "BBBBBB", "BBBBBB", "BBBBBB", "BBBBBE"],
49
                "answer": (["SBBBBB", "BBBBBB", "BBBBBB", "BBBBBB", "BBBBBE"], 13),
50
            },
51
            {
52
                "input": [
53
                    "S.......",
54
                    "........",
55
                    "..B.....",
56
                    ".....B..",
57
                    "........",
58
                    ".......E",
59
                ],
60
                "answer": (
61
                    [
62
                        "S.......",
63
                        "........",
64
                        "..B.....",
65
                        ".....B..",
66
                        "........",
67
                        ".......E",
68
                    ],
69
                    22,
70
                ),
71
            },
72
            {
73
                "input": [
74
                    "SW.B.W.",
75
                    ".W.W.W.",
76
                    ".W.W.W.",
77
                    ".W.W.WB",
78
                    ".W.W.W.",
79
                    ".B.W..E",
80
                ],
81
                "answer": (
82
                    ["SW.B.W.", ".W.W.W.", ".W.W.W.", ".W.W.WB", ".W.W.W.", ".B.W..E"],
83
                    35,
84
                ),
85
            },
86
        ],
87
        "4. Big": [
88
            {
89
                "input": [
90
                    "S..BW....",
91
                    "...W.....",
92
                    "..W......",
93
                    ".........",
94
                    ".WWWWWWW.",
95
                    "..WB.....",
96
                    "..W....B.",
97
                    "..WWW.WWW",
98
                    "....W...E",
99
                ],
100
                "answer": (
101
                    [
102
                        "S..BW....",
103
                        "...W.....",
104
                        "..W......",
105
                        ".........",
106
                        ".WWWWWWW.",
107
                        "..WB.....",
108
                        "..W....B.",
109
                        "..WWW.WWW",
110
                        "....W...E",
111
                    ],
112
                    38,
113
                ),
114
            },
115
            {
116
                "input": [
117
                    "S........",
118
                    ".WWW.WWW.",
119
                    ".W.B...W.",
120
                    ".WWWWWWW.",
121
                    ".W..B..W.",
122
                    ".W.WWW.WW",
123
                    ".W...W.WB",
124
                    ".WWW.W.W.",
125
                    ".....W..E",
126
                ],
127
                "answer": (
128
                    [
129
                        "S........",
130
                        ".WWW.WWW.",
131
                        ".W.B...W.",
132
                        ".WWWWWWW.",
133
                        ".W..B..W.",
134
                        ".W.WWW.WW",
135
                        ".W...W.WB",
136
                        ".WWW.W.W.",
137
                        ".....W..E",
138
                    ],
139
                    56,
140
                ),
141
            },
142
        ],
143
    }
144
145
    def check_solution(self, func, max_time, field):
146
        ACTIONS = {"L": (0, -1), "R": (0, 1), "U": (-1, 0), "D": (1, 0), "B": (0, 0)}
147
        max_row, max_col = len(field), len(field[0])
148
        s_row, s_col = 0, 0
149
        total_time = 0
150
        hold_box = True
151
        route = func(field[:])
152
        for step in route:
153
            if step not in ACTIONS:
154
                print("Unknown action {0}".format(step))
155
                return False
156 View Code Duplication
            if step == "B":
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
157
                if hold_box:
158
                    if field[s_row][s_col] == "B":
159
                        hold_box = False
160
                        total_time += 1
161
                        continue
162
                    else:
163
                        print("Stephan broke the cargo")
164
                        return False
165
                else:
166
                    if field[s_row][s_col] == "B":
167
                        hold_box = True
168
                    total_time += 1
169
                    continue
170
            n_row, n_col = s_row + ACTIONS[step][0], s_col + ACTIONS[step][1]
171
            total_time += 2 if hold_box else 1
172
            if 0 > n_row or n_row >= max_row or 0 > n_col or n_row >= max_col:
173
                print("We've lost Stephan.")
174
                return False
175
            if field[n_row][n_col] == "W":
176
                print("Stephan fell in water.")
177
                return False
178
            s_row, s_col = n_row, n_col
179
            if field[s_row][s_col] == "E" and hold_box:
180
                if total_time <= max_time:
181
                    return True
182
                else:
183
                    print("You can deliver the cargo faster.")
184
                    return False
185
        print("The cargo is not delivered")
186
        return False
187
188
    def test_Basics(self):
189
        for i in self.TESTS['1. Basics']:
190
            assert self.check_solution(checkio, i['answer'][1], i['answer'][0])
191
192
    def test_Extra(self):
193
        for i in self.TESTS['2. Extra']:
194
            assert self.check_solution(checkio, i['answer'][1], i['answer'][0])
195
196
    def test_Weird(self):
197
        for i in self.TESTS['3. Weird']:
198
            assert self.check_solution(checkio, i['answer'][1], i['answer'][0])
199
200
    def test_Big(self):
201
        for i in self.TESTS['4. Big']:
202
            assert self.check_solution(checkio, i['answer'][1], i['answer'][0])
203
204
205
if __name__ == "__main__":  # pragma: no cover
206
    unittest.main()
207