forked from KenMercusLai/checkio
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Parse Array.py
158 lines (140 loc) · 4.18 KB
/
Parse Array.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
WHITESPACE_STR = ' \t\n\r'
def parse_array(s, _w=WHITESPACE_STR, _sep=","):
array = None
stack = []
accumulator = ""
closed_flag = False
sep_flag = False
whitespace_flag = False
started_flag = False
for ch in s:
if ch in _w:
whitespace_flag = True
continue
if ch == "[":
if started_flag and not stack:
raise ValueError("Wrong string.")
if closed_flag or accumulator:
raise ValueError
in_array = []
if stack:
stack[-1](in_array)
else:
array = in_array
started_flag = True
stack.append(in_array.append)
elif not started_flag:
raise ValueError("Wrong string.")
elif ch == "]":
if not stack:
raise ValueError("Wrong string.")
if accumulator:
stack[-1](int(accumulator))
accumulator = ""
stack.pop()
closed_flag = True
sep_flag = False
whitespace_flag = False
elif ch in _sep:
if accumulator:
stack[-1](int(accumulator))
accumulator = ""
elif closed_flag:
pass
else:
raise ValueError("Wrong string.")
sep_flag = True
closed_flag = False
whitespace_flag = False
else:
if whitespace_flag and accumulator or closed_flag:
raise ValueError
accumulator += ch
whitespace_flag = False
if not closed_flag:
raise ValueError("Wrong string")
if stack:
raise ValueError("Wrong string")
if not array is None:
return array
else:
raise ValueError("Wrong string")
if __name__ == "__main__":
# These "asserts" using only for self-checking and not necessary for
# auto-testing
assert parse_array("[1, 2, 3]") == [1, 2, 3], "Simple"
assert parse_array("[[1], 2, 3]") == [[1], 2, 3], "Nested"
assert parse_array(
"[-3, [-2, 0], 10]") == [-3, [-2, 0], 10], "Negative integers"
assert parse_array("[100]") == [100], "One number"
assert parse_array("[2, 3]") == [2, 3], "Whitespaces"
assert parse_array("[[10, [11]], [[[1], 2], 3], 5]") == [
[10, [11]], [[[1], 2], 3], 5], "Deep nested"
assert parse_array(" [3, 4] ") == [3, 4], "Skip whitespaces"
assert parse_array("[[], 0]") == [[], 0], "Empty arrays"
assert parse_array("[[0,], 0]") == [[0], 0], "Comma - closed bracket"
try:
parse_array("[asd]")
assert False, "Only integers"
except ValueError:
pass
try:
parse_array("[2, 3]]")
assert False, "Excess bracket"
except ValueError:
pass
try:
parse_array("[++2, 1]")
assert False, "Two plus"
except ValueError:
pass
try:
parse_array("[10, 11, , 12]")
assert False, "Two separators"
except ValueError:
pass
try:
parse_array(" 13 ")
assert False, "Where is a list?"
except ValueError:
pass
try:
parse_array("[[2]")
assert False, "Excess opened bracket"
except ValueError:
pass
try:
parse_array("[3 4]")
assert False, "Check for spurious spaces within a number"
except ValueError:
pass
try:
parse_array("[10, 11,, 12]")
assert False, "Check for double separators without a space in between"
except ValueError:
pass
try:
parse_array("[[]3]")
assert False, "Check for missing separators after []"
except ValueError:
pass
try:
parse_array("[2[]]")
assert False, " Check for missing separators before []"
except ValueError:
pass
try:
parse_array("[3],")
assert False, "Excess separator"
except ValueError:
pass
try:
parse_array("[1,2]3")
assert False, "Excess number"
except ValueError:
pass
try:
parse_array("[1], [2,3]")
assert False, "Here should be only one array."
except ValueError:
pass